﻿if (typeof XMLHttpRequest == 'undefined') {
    XMLHttpRequest = function () {
        try {
            return new ActiveXObject('Msxml2.XMLHTTP.6.0');
        } catch (e) {}
        try {
            return new ActiveXObject('Msxml2.XMLHTTP.3.0');
        } catch (e) {}
        try {
            return new ActiveXObject('Msxml2.XMLHTTP');
        } catch (e) {}
        try {
            return new ActiveXObject('Microsoft.XMLHTTP');
        } catch (e) {}
        throw new Error('This browser does not support XMLHttpRequest.');
    };
}

function __namespaceTiLib() {
    var _version = 7.6;

    function __classGlobalCache() {
        var _self = this;
        var _globalCache = {};
        this.getItem = function (key) {
            return _globalCache[key];
        };
        this.setItem = function (key, value) {
            var previous = _globalCache[key];
            _globalCache[key] = value;
            return previous;
        };
        this.addItem = function (key, value) {
            if (!_globalCache[key]) {
                _globalCache[key] = value;
                return true;
            }
            return false;
        };
        this.removeItem = function (key) {
            if (_globalCache[key]) {
                delete _globalCache[key];
                return true;
            }
            return false;
        };
    }
    this.GlobalCache = new __classGlobalCache();

    function __namespaceTemplate() {
        var _self = this;
        this.createTemplate = function (template, data) {
            var template = new __classTemplate(template);
            if (data) {
                template = template.getTemplate(data);
            }
            return template;
        };
        this.createTemplates = function (templates) {
            var ts = {};
            for (key in templates) {
                ts[key] = _self.createTemplate(templates[key]);
            }
            return ts;
        };

        function __classTemplate(template) {
            var _t = _parse(template);
            this.getText = function (data) {
                var a = [];
                var c = _t.length;
                var i = 1;
                a.push(_t[0]);
                if (data) {
                    while (i < c) {
                        var d = _t[i++];
                        var key = d[0];
                        var value = data[key];
                        if (value !== undefined) {
                            a.push(value);
                        }
                        a.push(d[1]);
                    }
                } else {
                    while (i < c) {
                        d = _t[i++];
                        a.push(d[1]);
                    }
                }
                return a.join('');
            };
            this.getTemplate = function (data) {
                var a = [];
                var c = _t.length;
                var i = 1;
                a.push(_t[0]);
                while (i < c) {
                    var d = _t[i++];
                    var key = d[0];
                    var value = data[key];
                    if (value !== undefined) {
                        a.push(value);
                    } else {
                        a.push('_{');
                        a.push(key);
                        a.push('}_');
                    }
                    a.push(d[1]);
                }
                return new __classTemplate(a.join(''));
            };

            function _parse(template) {
                var t = template.split('_{');
                var c = t.length;
                for (var i = 1; i < c; i++) {
                    t[i] = t[i].split('}_');
                }
                return t;
            }
        }
    }
    this.Template = new __namespaceTemplate();

    function __namespaceParameter() {
        var _self = this;
        this.createParameter = function (names, values) {
            return new __classParameter(names, values);
        };

        function __classParameter(names, values) {
            var _names = names;
            var _values = values;

            function _getIndex(name) {
                var c = _names.length;
                for (var i = 0; i < c; ++i) {
                    if (name == _names[i]) {
                        return i;
                    }
                }
                return -1;
            }
            this.getJoinedNames = function (separator) {
                if (separator === undefined) {
                    separator = ',';
                }
                return _names.join(separator);
            };
            this.getJoinedValues = function (separator) {
                if (separator === undefined) {
                    separator = ',';
                }
                return _values.join(separator);
            };
            this.getJoinedParams = function (separator, equalsSign) {
                if (separator === undefined) {
                    separator = '&';
                }
                if (equalsSign === undefined) {
                    equalsSign = '=';
                }
                var sb = [];
                var c = _names.length;
                for (var i = 0; i < c; ++i) {
                    if (sb.length > 0) {
                        sb.push(separator);
                    }
                    sb.push(_names[i]);
                    sb.push(equalsSign);
                    sb.push(_values[i]);
                }
                return sb.join('');
            };
            this.getValue = function (name) {
                var index = _getIndex(name);
                if (index >= 0) {
                    return _values[index];
                } else {
                    return undefined;
                }
            };
            this.setValue = function (name, value) {
                var index = _getIndex(name);
                if (index >= 0) {
                    var v = _values[index];
                    _values[index] = value;
                    return v;
                } else {
                    return undefined;
                }
            };
            this.clone = function () {
                return new __classParameter(_names.slice(0), _values.slice(0));
            };
        }
    }
    this.Parameter = new __namespaceParameter();

    function __namespaceDocument() {
        var _self = this;
        this.getScrollHeight = function () {
            var h = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
            return h ? h : 0;
        };
        this.getScrollWidth = function () {
            var h = window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft;
            return h ? h : 0;
        };
        this.adjustIFrameSize = function (id) {
            var f = document.getElementById(id);
            if (f.document == null) {
                f.height = (f.contentDocument.body.offsetHeight + 60) + "px";
                f.width = (f.contentDocument.body.offsetWidth) + "px";
            } else {
                f.height = (document.frames(id).document.body.scrollHeight + 30) + "px";
                f.width = (document.frames(id).document.body.scrollWidth) + "px";
            }
        };
        this.disableRightClick = function () {
            document.oncontextmenu = function () {
                return false;
            };
        };
        this.getElementArea = function (id) {
            var e = document.getElementById(id);
            if (e) {
                var x = 0;
                var y = 0;
                var width = e.offsetWidth;
                var height = e.offsetHeight;
                var c;
                do {
                    c = (window.getComputedStyle) ? window.getComputedStyle(e, null) : 0;
                    x += e.offsetLeft + (c ? parseInt(c.getPropertyValue('border-left-width'), 10) : 0);
                    y += e.offsetTop + (c ? parseInt(c.getPropertyValue('border-top-width'), 10) : 0);
                    e = e.offsetParent;
                } while (e);
                return {
                    x: x,
                    y: y,
                    width: width,
                    height: height,
                    left: x,
                    top: y,
                    right: x + width,
                    bottom: y + height
                };
            }
            return null;
        };
        this.getInnerWidth = function () {
            var windowWidth = window.innerWidth || document.body.clientWidth;
            return windowWidth;
        };
        this.getInnerHeight = function () {
            var windowHeight = window.innerHeight || document.body.clientHeight;
            return windowHeight;
        };
        this.getDocumentHeight = function () {
            var documentHeight = document.body.scrollHeight;
            return documentHeight;
        }
        this.getDocumentWidth = function () {
            var documentWidth = document.body.scrollWidth;
            return documentWidth;
        }
    }
    this.Document = new __namespaceDocument();

    function __namespaceImage() {
        var _self = this;
        var _loadedImages = [];
        this.preLoadImages = function (images) {
            if (images && images.length > 0) {
                var i, j = this.loadedImages.length;
                for (i = 0; i < images.length; i++) {
                    if (images[i].indexOf("#") != 0) {
                        this.loadedImages[j] = new Image;
                        this.loadedImages[j++].src = images[i];
                    }
                }
            }
        };
    }
    this.Image = new __namespaceImage();

    function __namespaceEvent() {
        var _self = this;
        var _listenersByEvent = {};
        var _paramByEvent = {};
        var _newListenersByEvent = {};
        var _hasTimer = false;
        this.onEnter = function (e, func) {
            e = e ? e : window.event;
            if (e.keyCode == 13 && func) func();
        };

        function _dispatchEvent(event, listeners) {
            var hasListeners = false;
            if (!event) event = window.event;
            if (listeners) {
                var c = listeners.length;
                for (var i = 0; i < c; ++i) {
                    var listener = listeners[i];
                    if (listener) {
                        try {
                            listener(event);
                        } catch (ex) {}
                    }
                }
            }
        };

        function _dispatchEventMouseDown(event) {
            _dispatchEvent(event, _listenersByEvent['mousedown']);
        }

        function _dispatchEventMouseUp(event) {
            _dispatchEvent(event, _listenersByEvent['mouseup']);
        }

        function _dispatchEventMouseMove(event) {
            _dispatchEvent(event, _listenersByEvent['mousemove']);
        }

        function _dispatchEventContextMenu(event) {
            _dispatchEvent(event, _listenersByEvent['contextmenu']);
        }

        function _dispatchEventKeyDown(event) {
            _dispatchEvent(event, _listenersByEvent['keydown']);
        }

        function _dispatchEventByTimer() {
            var oldParam = _paramByEvent['viewportsize'];
            var newParam = _getViewPortSize();
            if (!oldParam || newParam.width != oldParam.width || newParam.height != oldParam.height) {
                if (oldParam) {
                    newParam.oldWidth = oldParam.width;
                    newParam.oldHeight = oldParam.height;
                }
                _dispatchEvent(newParam, _listenersByEvent['viewportsize']);
                _paramByEvent['viewportsize'] = newParam;
            } else {
                _dispatchEvent(newParam, _newListenersByEvent['viewportsize']);
            }
            _newListenersByEvent['viewportsize'] = null;
            oldParam = _paramByEvent['scroll'];
            newParam = {
                x: window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft,
                y: window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop
            };
            if (!oldParam || newParam.x != oldParam.x || newParam.y != oldParam.y) {
                if (oldParam) {
                    newParam.oldX = oldParam.x;
                    newParam.oldY = oldParam.y;
                }
                _dispatchEvent(newParam, _listenersByEvent['scroll']);
                _paramByEvent['scroll'] = newParam;
            } else {
                _dispatchEvent(newParam, _newListenersByEvent['scroll']);
            }
            _newListenersByEvent['scroll'] = null;
            var listeners = _listenersByEvent['viewportsize'];
            if ((_listenersByEvent['scroll'] && _listenersByEvent['scroll'].length > 0) || (_listenersByEvent['viewportsize'] && _listenersByEvent['viewportsize'].length > 0)) {
                setTimeout(function () {
                    _dispatchEventByTimer();
                }, 200);
            }
        }

        function _getViewPortSize() {
            var viewport = {
                width: 0,
                height: 0
            };
            if (typeof window.innerWidth != 'undefined') {
                viewport.width = window.innerWidth, viewport.height = window.innerHeight
            } else if (typeof document.documentElement != 'undefined' && typeof document.documentElement.clientWidth != 'undefined' && document.documentElement.clientWidth != 0) {
                viewport.width = document.documentElement.clientWidth, viewport.height = document.documentElement.clientHeight
            } else {
                viewport.width = document.getElementsByTagName('body')[0].clientWidth, viewport.height = document.getElementsByTagName('body')[0].clientHeight
            }
            return viewport;
        }
        this.getViewPortSize = function () {
            return _getViewPortSize();
        };
        this.addListener = function (type, listener) {
            switch (type) {
            case 'mousedown':
            case 'mouseup':
            case 'mousemove':
            case 'contextmenu':
            case 'viewportsize':
            case 'scroll':
            case 'keydown':
                var listeners = _listenersByEvent[type];
                if (!listeners) {
                    listeners = [];
                    _listenersByEvent[type] = listeners;
                    switch (type) {
                    case 'mousedown':
                        document.onmousedown = _dispatchEventMouseDown;
                        break;
                    case 'mouseup':
                        document.onmouseup = _dispatchEventMouseUp;
                        break;
                    case 'mousemove':
                        document.onmousemove = _dispatchEventMouseMove;
                        break;
                    case 'contextmenu':
                        document.oncontextmenu = _dispatchEventContextMenu;
                        break;
                    case 'viewportsize':
                    case 'scroll':
                        if (!_hasTimer) {
                            setTimeout(function () {
                                _dispatchEventByTimer();
                            }, 200);
                        }
                        break;
                    case 'keydown':
                        document.onkeydown = _dispatchEventKeyDown;
                        break;
                    }
                }
                var c = listeners.length;
                for (var i = 0; i < c; ++i) {
                    if (listener == listeners[i]) {
                        return;
                    }
                }
                listeners.push(listener);
                switch (type) {
                case 'viewportsize':
                case 'scroll':
                    listeners = _newListenersByEvent[type];
                    if (!listeners) {
                        listeners = [];
                        _newListenersByEvent[type] = listeners;
                    }
                    listeners.push(listener);
                    break;
                }
            }
        };
        this.removeListener = function (type, listener) {
            switch (type) {
            case 'mousedown':
            case 'mouseup':
            case 'mousemove':
            case 'contextmenu':
            case 'viewportsize':
            case 'keydown':
                var listeners = _listenersByEvent[type];
                if (listeners) {
                    var newListeners = [];
                    var c = listeners.length;
                    for (var i = 0; i < c; ++i) {
                        var l = listeners[i];
                        if (listener != l) {
                            newListeners.push(l);
                        }
                    }
                    if (newListeners.length > 0) {
                        _listenersByEvent[type] = newListeners;
                    } else {
                        delete _listenersByEvent[type];
                        switch (type) {
                        case 'mousedown':
                        case 'mouseup':
                        case 'mousemove':
                        case 'contextmenu':
                        case 'keydown':
                            document['on' + type] = null;
                            break;
                        }
                    }
                }
            }
        };
    }
    this.Event = new __namespaceEvent();

    function __namespaceWindow() {
        var _self = this;
        var _windows = {};
        this.getWindow = function (name) {
            var w = _windows[name];
            if (w) {
                if (!w.closed) {
                    return w;
                }
                delete _windows[name];
            }
            return null;
        };
        this.setWindow = function (window) {
            if (window && window.name) {
                _windows[window.name] = window;
            }
        };
        this.openWindow = function (url, name, params) {
            var w = name ? (params ? window.open(url, name, params) : window.open(url, name)) : window.open(url);
            if (w) {
                if (w.blur) {
                    w.blur();
                }
                if (w.focus) {
                    w.focus();
                }
            }
            return w;
        };
        this.informOpener = function () {
            if (window.opener) {
                try {
                    var til = window.opener.TiLib;
                    if (til) {
                        til.Window.setWindow(this);
                    }
                } catch (e) {}
            }
            setTimeout('TiLib.Window.informOpener();', 100);
        };
    };
    this.Window = new __namespaceWindow();

    function __namespaceAjax() {
        var _self = this;
        var _requests = {};
        this.sendRequest = function (name, url, onCallback, onError) {
            var r = _createRequest(name, onCallback, onError);
            if (!r.sending) {
                r.sending = true;
                r.request.open('GET', url, (name != undefined) ? true : false);
                r.request.onreadystatechange = r.request.onreadystatechange;
                r.request.send(null);
                return true;
            } else if (r.request && r.request.abort) {
                r.request.abort();
                _requests[name] = null;
                r = _createRequest(name, onCallback, onError);
                r.sending = true;
                r.request.open('GET', url, (name != undefined) ? true : false);
                r.request.onreadystatechange = r.request.onreadystatechange;
                r.request.send(null);
            }
            return false;
        };
        this.postRequest = function (name, url, param, onCallback, onError) {
            var r = _createRequest(name, onCallback, onError);
            if (!r.sending) {
                r.sending = true;
                r.request.open('POST', url, (name != undefined) ? true : false);
                r.request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
                r.request.onreadystatechange = r.request.onreadystatechange;
                r.request.send(param);
                return true;
            } else if (r.request && r.request.abort) {
                r.request.abort();
                _requests[name] = null;
                r = _createRequest(name, onCallback, onError);
                r.sending = true;
                r.request.open('POST', url, (name != undefined) ? true : false);
                r.request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
                r.request.onreadystatechange = r.request.onreadystatechange;
                r.request.send(param);
            }
            return false;
        };
        this.onLoadExecution = function (id) {
            var f = document.getElementById(id);
            if (f) {
                var w = f.contentWindow;
                if (w) {
                    var c;
                    if (w.document.body) {
                        if (typeof (w.document.body.innerText) != 'undefined') {
                            c = w.document.body.innerText;
                        } else if (typeof (w.document.body.textContent) != 'undefined') {
                            c = w.document.body.textContent;
                        } else if (typeof (w.document.body.innerHTML) != 'undefined') {
                            c = w.document.body.innerHTML;
                        }
                    }
                    if (c) {
                        eval(c);
                    }
                }
            }
        };

        function _createRequest(name, onCallback, onError) {
            var r;
            if (name) {
                r = _requests[name];
            }
            if (!r) {
                r = {
                    sending: false,
                    request: new XMLHttpRequest()
                };
                r.request.onprogress = function () {};
                r.request.ontimeout = function () {};
                r.request.onerror = function () {};
                r.request.onreadystatechange = function () {
                    if (r.request.readyState == 4) {
                        r.sending = false;
                        if (r.request.status == 200) {
                            if (onCallback) {
                                onCallback(r.request.responseText);
                            } else {
                                var c = r.request.responseText;
                                if (c) {
                                    eval(c);
                                }
                            }
                        } else if (onError) {
                            onError(r.request.status);
                        }
                    }
                }
                _requests[name] = r;
            }
            return r;
        }
    };
    this.Ajax = new __namespaceAjax();

    function __namespaceTimer() {
        var _self = this;
        var _modules = [];
        this.setTimeout = function (timeout, method, args) {
            if (!isNaN(timeout) && method) {
                if (args) {
                    setTimeout(method + '(' + args.join(',') + ');', timeout);
                } else {
                    setTimeout(method + '();', timeout);
                }
            }
        };
        this.addToSecondTimer = function (module) {
            if (module) {
                _modules.push(module);
            }
        };
        this.startSecondTimer = function () {
            var c = _modules.length;
            for (var i = 0; i < c; ++i) {
                var module = _modules[i];
                if (module && module.onTime) {
                    try {
                        module.onTime();
                    } catch (e) {
                        if (typeof console === 'object' && console.log) {
                            console.log(e);
                        }
                    }
                }
            }
            setTimeout(function () {
                _self.startSecondTimer();
            }, 1000);
        };
    };
    this.Timer = new __namespaceTimer();

    function __namespaceDate() {
        var _self = this;
        this.parseDate = function (text, format) {
            if (format) {
                format = format.toLowerCase();
                var h = 0;
                var m = 0;
                while (1) {
                    switch (format) {
                    case 'yyyymmddhhmm':
                        h = parseInt(text.substring(8, 10), 10);
                        if (isNaN(h)) h = 0;
                        m = parseInt(text.substring(10, 12), 10);
                        if (isNaN(m)) m = 0;
                        format = format.substring(0, 8);
                        break;
                    case 'yyyymmdd':
                        return new Date(parseInt(text.substring(0, 4), 10), parseInt(text.substring(4, 6), 10) - 1, parseInt(text.substring(6, 8), 10), h, m);
                    case 'yyyy-mm-dd hh:mm':
                    case 'mm/dd/yyyy hh:mm':
                        var h = parseInt(text.substring(11, 13), 10);
                        if (isNaN(h)) h = 0;
                        var m = parseInt(text.substring(14, 16), 10);
                        if (isNaN(m)) m = 0;
                        format = format.substring(0, 10);
                        break;
                    case 'yyyy-mm-dd':
                        return new Date(parseInt(text.substring(0, 4), 10), parseInt(text.substring(5, 7), 10) - 1, parseInt(text.substring(8, 10), 10), h, m);
                    case 'mm/dd/yyyy':
                        return new Date(parseInt(text.substring(6, 10), 10), parseInt(text.substring(0, 2), 10) - 1, parseInt(text.substring(3, 5), 10), h, m);
                    default:
                        return undefined;
                    }
                }
            }
            return undefined;
        };
        this.getTimezone = function () {
            return (new Date()).getTimezoneOffset();
        };
        this.getTimeOffset = function () {
            var now = new Date();
            var date1 = new Date(now.getFullYear(), 0, 1, 0, 0, 0, 0);
            var date2 = new Date(now.getFullYear(), 6, 1, 0, 0, 0, 0);
            var tmp = date1.toUTCString();
            var date3 = new Date(tmp.substring(0, tmp.lastIndexOf(' ') - 1));
            tmp = date2.toUTCString();
            var date4 = new Date(tmp.substring(0, tmp.lastIndexOf(' ') - 1));
            var minutesDiffStdTime = (date1 - date3) / (1000 * 60);
            var minutesDiffDaylightTime = (date2 - date4) / (1000 * 60);
            var gmt = minutesDiffStdTime > minutesDiffDaylightTime ? minutesDiffDaylightTime : minutesDiffStdTime;
            return gmt;
        };
        this.isDaylightSaving = function () {
            var now = new Date();
            var date1 = new Date(now.getFullYear(), 0, 1, 0, 0, 0, 0);
            var date2 = new Date(now.getFullYear(), 6, 1, 0, 0, 0, 0);
            var tmp = date1.toUTCString();
            var date3 = new Date(tmp.substring(0, tmp.lastIndexOf(' ') - 1));
            tmp = date2.toUTCString();
            var date4 = new Date(tmp.substring(0, tmp.lastIndexOf(' ') - 1));
            var minutesDiffStdTime = (date1 - date3) / (1000 * 60);
            var minutesDiffDaylightTime = (date2 - date4) / (1000 * 60);
            return (minutesDiffStdTime != minutesDiffDaylightTime);
        };
    };
    this.Date = new __namespaceDate();

    function __namespaceNumber() {
        var _self = this;
        this.compareNumber = function (n1, n2) {
            return _self.compareNumberAsc(n1, n2);
        };
        this.compareNumberAsc = function (n1, n2) {
            return n1 - n2;
        };
        this.compareNumberDesc = function (n1, n2) {
            return -_self.compareNumberAsc(n1, n2);
        };
        this.roundDown = function (number, fractionDigits) {
            var value = parseFloat(number);
            var d = 1;
            if (fractionDigits) {
                for (var i = 0; i < fractionDigits; ++i) {
                    d *= 10;
                }
                value = parseFloat(value.toFixed(fractionDigits + 1));
            }
            value *= d;
            value = Math.floor(value);
            value = value / d;
            if (fractionDigits) {
                value = parseFloat(value.toFixed(fractionDigits));
            }
            return value;
        };
        this.roundUp = function (number, fractionDigits) {
            var value = parseFloat(number);
            var d = 1;
            if (fractionDigits) {
                for (var i = 0; i < fractionDigits; ++i) {
                    d *= 10;
                }
                value = parseFloat(value.toFixed(fractionDigits + 1));
            }
            value *= d;
            value = Math.ceil(value);
            value = value / d;
            if (fractionDigits) {
                value = parseFloat(value.toFixed(fractionDigits));
            }
            return value;
        };
        this.round = function (number, fractionDigits) {
            var value = parseFloat(number);
            var d = 1;
            if (fractionDigits) {
                for (var i = 0; i < fractionDigits; ++i) {
                    d *= 10;
                }
                value = parseFloat(value.toFixed(fractionDigits + 1));
            }
            value *= d;
            value = Math.round(value);
            value = value / d;
            if (fractionDigits) {
                value = parseFloat(value.toFixed(fractionDigits));
            }
            return value;
        };
        this.toString = function (number, maxFractionDigits, minFractionDigits) {
            var value = parseFloat(number);
            if (maxFractionDigits !== undefined) {
                if (minFractionDigits !== undefined && minFractionDigits < maxFractionDigits) {
                    for (var d = maxFractionDigits; d > minFractionDigits; --d) {
                        var text = value.toFixed(d);
                        if (text.charAt(text.length - 1) != '0') {
                            return text;
                        }
                    }
                    return value.toFixed(minFractionDigits);
                }
                return value.toFixed(maxFractionDigits);
            } else {
                return value.toString();
            }
        };
    };
    this.Number = new __namespaceNumber();

    function __namespaceText() {
        var _self = this;
        this.trimStart = function (str) {
            return str.replace(/^\s+/, '');
        };
        this.trimEnd = function (str) {
            return str.replace(/\s+$/, '');
        };
        this.trim = function (str) {
            str = _self.trimStart(str);
            str = _self.trimEnd(str);
            return str;
        };
        this.encodeHTML = function (str) {
            var sb = [];
            if (str) {
                var c = str.length;
                for (var i = 0; i < c; ++i) {
                    var a = str.charAt(i);
                    switch (a) {
                    case '\'':
                        sb.push('&#39;');
                        break;
                    case '"':
                        sb.push('&#34;');
                        break;
                    case '<':
                        sb.push('&lt;');
                        break;
                    case '>':
                        sb.push('&gt;');
                        break;
                    case '$':
                        sb.push('&#36;');
                        break;
                    case '&':
                        sb.push('&#38;');
                        break;
                    default:
                        sb.push(a);
                    }
                }
            }
            return sb.join('');
        };
        this.encodeUrl = function (str) {
            return encodeURIComponent(str);
        };
        this.decodeUrl = function (str) {
            return decodeURIComponent(str);
        };
        this.compareString = function (s1, s2) {
            return _self.compareStringAsc(s1, s2);
        };
        this.compareStringAsc = function (s1, s2) {
            var r = 0;
            if (s1 && s2) {
                s1 = s1 + '';
                s2 = s2 + '';
                var c = s1.length;
                if (s1.length > s2.length) {
                    r = 1;
                    c = s2.length;
                } else if (s1.length < s2.length) {
                    r = -1;
                }
                for (var i = 0; i < c; ++i) {
                    if (s1.charAt(i) > s2.charAt(i)) {
                        r = 1;
                        break;
                    } else if (s1.charAt(i) < s2.charAt(i)) {
                        r = -1;
                        break;
                    }
                }
            } else if (s1) {
                r = 1;
            } else if (s2) {
                r = -1;
            }
            return r;
        };
        this.compareStringDesc = function (s1, s2) {
            return -_self.compareStringAsc(s1, s2);
        };
        this.addClassItem = function (classValue, item) {
            var items = [];
            if (classValue) {
                var values = classValue.split(' ');
                for (var i = 0; i < values.length; ++i) {
                    var value = values[i];
                    if (value && value.length > 0) {
                        items.push(value);
                        if (value == item) {
                            item = null;
                        }
                    }
                }
            }
            if (item) {
                items.push(item);
            }
            return items.join(' ');
        };
        this.removeClassItem = function (classValue, item) {
            var items = [];
            if (classValue) {
                var values = classValue.split(' ');
                for (var i = 0; i < values.length; ++i) {
                    var value = values[i];
                    if (value && value.length > 0 && value != item) {
                        items.push(value);
                    }
                }
            }
            return items.join(' ');
        };
    };
    this.Text = new __namespaceText();

    function __namespaceBrowser() {
        var _self = this;
        var _browserInfo = null;
        this.getBrowserInfo = function () {
            if (!_browserInfo) {
                _browserInfo = {};
                var ua = navigator.userAgent.toLowerCase();
                if (ua.indexOf("android") >= 0) {
                    _browserInfo.isMobileDevice = true;
                } else if (ua.indexOf("blackberry") >= 0) {
                    _browserInfo.isMobileDevice = true;
                } else if (ua.indexOf("iphone") >= 0) {
                    _browserInfo.isMobileDevice = true;
                } else if (ua.indexOf("ipad") >= 0) {
                    _browserInfo.isMobileDevice = true;
                } else if (ua.indexOf("ipod") >= 0) {
                    _browserInfo.isMobileDevice = true;
                } else if (ua.indexOf("opera mini") >= 0) {
                    _browserInfo.isMobileDevice = true;
                } else if (ua.indexOf("iemobile") >= 0) {
                    _browserInfo.isMobileDevice = true;
                } else {
                    _browserInfo.isMobileDevice = false;
                }
                if ((index = ua.indexOf('msie')) >= 0) {
                    _browserInfo.name = 'Internet Explorer';
                    ua = ua.substring(index + 5);
                } else {
                    if ((index = ua.indexOf('palemoon')) >= 0) {
                        _browserInfo.name = 'Palemoon';
                    } else if ((index = ua.indexOf('firefox')) >= 0) {
                        _browserInfo.name = 'Firefox';
                    } else if ((index = ua.indexOf('chrome')) >= 0) {
                        _browserInfo.name = 'Chrome';
                    } else if ((index = ua.indexOf('safari')) >= 0) {
                        _browserInfo.name = 'Safari';
                    } else if ((index = ua.indexOf('opera')) >= 0) {
                        _browserInfo.name = 'Opera';
                    } else {
                        return _browserInfo;
                    }
                    ua = ua.substring(index + _browserInfo.name.length + 1);
                }
                _browserInfo.version = parseInt(ua);
            }
            return _browserInfo;
        };
        this.getName = function () {
            return _self.getBrowserInfo().name;
        };
        this.getVersion = function () {
            return _self.getBrowserInfo().version;
        };
        this.isMobileDevice = function () {
            return _self.getBrowserInfo().isMobileDevice;
        };
        this.isInternetExplorer = function () {
            return _self.getName() == 'Internet Explorer' ? true : false;
        };
        this.isPalemoon = function () {
            return _self.getName() == 'Palemoon' ? true : false;
        };
        this.isFirefox = function () {
            return _self.getName() == 'Firefox' ? true : false;
        };
        this.isChrome = function () {
            return _self.getName() == 'Chrome' ? true : false;
        };
        this.isSafari = function () {
            return _self.getName() == 'Safari' ? true : false;
        };
        this.isOpera = function () {
            return _self.getName() == 'Opera' ? true : false;
        };
        this.hasFlash = function () {
            if (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"] && navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin) {
                return true;
            } else {
                try {
                    var ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
                    return true;
                } catch (e) {
                    return false;
                }
            }
        };
    };
    this.Browser = new __namespaceBrowser();

    function __namespaceUI() {
        var _self = this;
        var _isEffectSupported = true;
        this.isEffectSupported = function () {
            if (_isEffectSupported && typeof (jQuery) != 'undefined' && !TiLib.Browser.isMobileDevice()) {
                return true;
            }
            return false;
        };
        this.enableEffect = function (enabled) {
            _isEffectSupported = enabled;
            return _self.isEffectSupported();
        };
        this.addCollapseEffect = function (elementId, duration, completeFunction) {
            if (_self.isEffectSupported()) {
                var e = $('#' + elementId);
                if (e && e.css && e.slideUp) {
                    e.stop();
                    e.css('display', 'block');
                    e.slideUp(duration, completeFunction);
                }
                return true;
            }
            return false;
        };
        this.addExpandEffect = function (elementId, duration, completeFunction) {
            if (_self.isEffectSupported()) {
                var e = $('#' + elementId);
                if (e && e.css && e.slideUp) {
                    e.stop();
                    e.css('display', 'none');
                    e.slideDown(duration, completeFunction);
                }
                return true;
            }
            return false;
        };
        this.addMoveVerticalEffect = function (elementId, fromPixel, toPixel, duration) {
            if (_self.isEffectSupported()) {
                var e = $('#' + elementId);
                if (e && e.animate) {
                    if (fromPixel != null && fromPixel != undefined) {
                        e.css('top', fromPixel + 'px');
                    }
                    e.animate({
                        'top': toPixel + 'px'
                    }, duration);
                }
                return true;
            }
            return false;
        };
        this.addAnimatePropertyEffect = function (elementId, property, duration, toValue, fromValue) {
            if (_self.isEffectSupported()) {
                var e = $('#' + elementId);
                if (e && e.animate) {
                    if (fromValue != null && fromValue != undefined) {
                        e.css(property, fromValue + 'px');
                    }
                    e.animate({
                        property: toValue + 'px'
                    }, duration);
                }
                return true;
            }
            return false;
        };
    };
    this.UI = new __namespaceUI();

    function __namespaceCookie() {
        var _self = this;
        this.getValue = function (name) {
            var nameEQ = name + '=';
            var ca = document.cookie.split(';');
            for (var i = 0; i < ca.length; i++) {
                var c = ca[i];
                while (c.charAt(0) == ' ') c = c.substring(1, c.length);
                if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
            }
            return null;
        };
        this.setValue = function (name, value, seconds) {
            var expires = '';
            if (seconds) {
                var date = new Date();
                date.setTime(date.getTime() + (seconds * 1000));
                expires = '; expires=' + date.toGMTString();
            }
            document.cookie = name + '=' + value + expires + '; path=/';
        };
        this.getNames = function (prefix) {
            var names = [];
            var ca = document.cookie.split(';');
            for (var i = 0; i < ca.length; i++) {
                var c = ca[i];
                while (c.charAt(0) == ' ') c = c.substring(1, c.length);
                var eqIndex = c.indexOf('=');
                if (eqIndex > 0) {
                    var name = c.substring(0, eqIndex);
                    if (name.length > 0) {
                        if (!prefix || name.indexOf(prefix) == 0) {
                            names.push(name);
                        }
                    }
                }
            }
            return names;
        };
    };
    this.Cookie = new __namespaceCookie();

    function __namespaceUrl() {
        var _self = this;
        this.buildQueryString = function (params) {
            if (params) {
                var sb = [];
                for (var key in params) {
                    var value = params[key];
                    if (sb.length > 0) {
                        sb.push('&');
                    }
                    sb.push(key);
                    sb.push('=');
                    sb.push(value);
                }
                return sb.join('');
            }
            return '';
        };
        this.getQueryParams = function (w) {
            if (!w) w = window;
            var params = {};
            var index = w.location.href.indexOf('?');
            if (index > 0) {
                var query = w.location.href.substring(index + 1);
                var index = query.indexOf('#');
                if (index > 0) {
                    query = query.substring(0, index);
                }
                var ps = query.split('&');
                var c = ps.length;
                var p;
                for (var i = 0; i < c; ++i) {
                    p = ps[i];
                    index = p.indexOf('=');
                    params[p.substring(0, index)] = p.substring(index + 1);
                }
            }
            return params;
        };
        this.getFragment = function () {
            var index = window.location.href.indexOf('#');
            if (index > 0) {
                var fragment = window.location.href.substring(index + 1);
                if (fragment && fragment.length > 0) {
                    return fragment;
                }
            }
            return '';
        };
    };
    this.Url = new __namespaceUrl();

    function __namespaceValidator() {
        var _self = this;
        this.getPasswordStrength = function (password) {
            var score = 1;
            if (password.length < 8) return 1;
            if (password.match(/[a-z]/)) score++;
            if (password.match(/[A-Z]/)) score++;
            if (password.match(/\d+/)) score++;
            if (password.match(/.[!,@,#,$,%,^,&,*,?,_,~,-,(,)]/)) score++;
            return score;
        };
        var _emailPattern = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
        this.isEmail = function (str) {
            return (str && _emailPattern.test(str)) ? true : false;
        };
        var _numberPattern = /^[1-9]\d*$/;
        this.isNumber = function (str) {
            return (str && _numberPattern.test(str)) ? true : false;
        };
        var _numberStringPattern = /^\d+$/;
        this.isNumberString = function (str) {
            return (str && _numberStringPattern.test(str)) ? true : false;
        };
        var _numbericPattern = /^[-]?\d*(\.\d+)?$/;
        this.isNumeric = function (str) {
            return (str && _numbericPattern.test(str)) ? true : false;
        };
        var _alphabetPattern = /^[a-zA-Z ]+$/;
        this.isAlphabetString = function (str) {
            return (str && _alphabetPattern.test(str)) ? true : false;
        };
        this.validateString = function (str, minLength, maxLength) {
            if ((!str) || (minLength && str.length < minLength) || (maxLength && str.length > maxLength)) {
                return false;
            }
            return false;
        };
        var _postCodePatternGB = /^[a-z0-9](\s|[a-z0-9])+[a-z0-9]$/;
        var _postCodePattern = /^[a-z0-9][a-z0-9\s]+[a-z0-9]$/;
        this.validatePostCode = function (str, country) {
            if (str) {
                str = str.toLowerCase();
            } else {
                return false;
            }
            if (country) {
                country = country.toLowerCase();
            }
            switch (country) {
            case 'gb':
                return (str.length >= 3 && str.length <= 15 && _postCodePatternGB.test(str)) ? true : false;
            default:
                return (_postCodePattern.test(str)) ? true : false;
            };
        };
        this.validatePhoneNo = function (phoneNo, areaCode, countryCode) {
            if (_self.validateString(countryCode, 1, 8) && _self.isNumberString(countryCode) && (!areaCode || _self.isNumberString(areaCode)) && _self.validateString(phoneNo, 5, 20) && _self.isNumberString(phoneNo)) {
                return true;
            }
            return false;
        };
        this.validateDate = function (year, month, date) {
            if (year && month && date) {
                var date = new Date(year, month, date);
                if (date) {
                    return true;
                }
            }
            return false;
        };
    };
    this.Validator = new __namespaceValidator();

    function _prototypeArray() {
        var a = [];
        a.constructor.prototype.updateArray = function (updating, startIndex) {
            var array = this.slice(0);
            if (!updating) return array;
            if (startIndex === undefined) {
                startIndex = 0;
            }
            var c = updating.length;
            for (var i = 0; i < c; ++i) {
                var d = updating[i];
                if (d != undefined) {
                    if (Object.prototype.toString.call(d) === '[object Array]') {
                        if (d.length && array[i + startIndex]) {
                            array[i + startIndex] = array[i + startIndex].updateArray(d);
                        } else {
                            array[i + startIndex] = d;
                        }
                    } else {
                        array[i + startIndex] = d;
                    }
                }
            }
            return array;
        };
        a.constructor.prototype.contains = function (item) {
            if (item !== undefined) {
                var c = this.length;
                for (var i = 0; i < c; i++) {
                    if (this[i] == item) {
                        return true;
                    }
                }
            }
            return false;
        };
    };
    _prototypeArray();

    function __namepsaceJSON() {
        var _self = this;
        this.parse = function (json) {
            var func = new Function("return " + json);
            return func();
        }
    }
    this.JSON = new __namepsaceJSON();

    function __namepsaceDictionaryUtil() {
        this.getSortedKeys = function (dictionary, compareKeyFunction) {
            var keys = [];
            for (var key in dictionary) {
                keys.push(key);
            }
            if (compareKeyFunction) {
                keys.sort(compareKeyFunction);
            } else {
                keys.sort();
            }
            return keys;
        };
        this.getSortedValuesByKey = function (dictionary, compareKeyFunction) {
            var keys = [];
            for (var key in dictionary) {
                keys.push(key);
            }
            if (compareKeyFunction) {
                keys.sort(compareKeyFunction);
            } else {
                keys.sort();
            }
            var values = [];
            var c = keys.length;
            for (var i = 0; i < c; ++i) {
                values.push(dictionary[keys[i]]);
            }
            return values;
        };
        this.getSortedValuesByValue = function (dictionary, compareValueFunction) {
            var values = [];
            for (var key in dictionary) {
                values.push(dictionary[key]);
            }
            if (compareValueFunction) {
                values.sort(compareValueFunction);
            } else {
                values.sort();
            }
            return values;
        };
    }
    this.DictionaryUtil = new __namepsaceDictionaryUtil();
}
var TiLib = new __namespaceTiLib();

function __Module_PageContainer() {
    var _self = this;
    var _modules = {
        'top-banner': null,
        'top-slider': null,
        'sport-market': null,
        'ticket': null,
        'my-bets': null,
        'right-event': null,
        'mini-bet-list': null
    };
    this.getModule = function (name) {
        return _modules[name];
    }
    this.setModule = function (name, module) {
        _modules[name] = module;
    }
    var _pageParam = null;
    this.initiate = function () {
        for (var m in _modules) {
            var module = _modules[m];
            if (module && module.initiate) {
                module.initiate();
            }
        }
    };
    this.onTemplate = function (name, value) {
        var version = TiLib.GlobalCache.getItem('tmplversion');
        var langCode = TiLib.GlobalCache.getItem('lang');
        if (!langCode) langCode = 'en';
        TiLib.GlobalCache.setItem('template-' + name + '-' + langCode + '-' + version, value);
        for (var m in _modules) {
            var module = _modules[m];
            if (module && module.onTemplate) {
                module.onTemplate(name);
            }
        }
    };
    this.getTemplate = function (name) {
        var version = TiLib.GlobalCache.getItem('tmplversion');
        var langCode = TiLib.GlobalCache.getItem('lang');
        if (!langCode) langCode = 'en';
        var template = TiLib.GlobalCache.getItem('template-' + name + '-' + langCode + '-' + version);
        if (template) {
            return template;
        }
        TiLib.Ajax.sendRequest('template-' + name, '/web-root/restricted/template.aspx?name=' + name + '&lang=' + langCode + '&version=' + version);
        return null;
    };
    this.onTime = function () {
        if (_submodule && _submodule.onTime) {
            _submodule.onTime();
        }
    };
    this.onClick = function (event, moduleName) {
        if (moduleName) {
            var module = _modules[moduleName];
            if (module && module.onClick) {
                return module.onClick(event);
            }
        }
        if (!event) event = window.event;
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    };

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'page') {}
        }
        return true;
    }
    this.draw = function () {
        if (_submodule && _submodule.draw) {
            _submodule.draw();
        }
    };
    this.toggleDiv = function (id) {
        var div = document.getElementById(id);
        if (div) {
            if (div.className.indexOf('hide') >= 0) {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            }
        }
    };
}
var $P = new __Module_PageContainer();

function $M(name) {
    return $P.getModule(name);
}

function __Module_CookieSettingMonitor() {
    var _ModuleSettingPrefix = 'module-setting-';
    var _self = this;
    var _settingTime = {};
    TiLib.Timer.addToSecondTimer(_self);
    this.onTime = function () {
        var names = CookieHelper.getNames(_ModuleSettingPrefix);
        var c = names.length;
        for (var i = 0; i < c; ++i) {
            var time = CookieHelper.getValue(names[i]);
            if (!time) {
                time = (new Date()).getTime();
            }
            var moduleName = names[i].substring(_ModuleSettingPrefix.length);
            if (_settingTime[moduleName] == undefined || _settingTime[moduleName] < time) {
                _settingTime[moduleName] = time;
                var module = $M(moduleName);
                if (module && module.onSettingChanged) {
                    module.onSettingChanged();
                }
            }
        }
    };
}

function __Cache_SportMarket() {
    var _sportDictionary = {};
    var _marketPageDictionary = {};
    var _sportArray = [];
    var _sportMarketPageCountDict = {};
    var _defaultMarketPage = 1;
    var _totalParlayCount = 0;
    var _sportNameDictionary = {};
    var _marketPageNameDictionary = {};
    this.update = function (data) {
        var sportArray = data[0];
        var marketPageArray = data[1];
        _sportMarketPageCountDict = data[2];
        _totalParlayCount = data[3];
        _defaultMarketPage = data[4];
        _sportArray = sportArray;
        _sportDictionary = {};
        for (var i = 0; i < sportArray.length; ++i) {
            var sport = sportArray[i];
            var sportId = sport[0];
            _sportDictionary[sportId] = sport;
            if (sport[1]) {
                _sportNameDictionary[sportId] = sport[1];
            }
        }
        _marketPageDictionary = {};
        for (i = 0; i < marketPageArray.length; ++i) {
            var marketPage = marketPageArray[i];
            var marketId = marketPage[0];
            _marketPageDictionary[marketId] = marketPage;
            if (marketPage[1]) {
                _marketPageNameDictionary[marketId] = marketPage[1];
            }
        }
    };
    this.getSportArray = function () {
        return _sportArray;
    };
    this.getMarketPage = function (marketPageId) {
        return _marketPageDictionary[marketPageId];
    };
    this.getSportMarketPageCount = function (sportId) {
        return _sportMarketPageCountDict[sportId];
    };
    this.getDefaultMarketPage = function () {
        return _defaultMarketPage;
    };
    this.getTotalParlayCount = function () {
        return _totalParlayCount;
    };
    this.getSportName = function (sportId) {
        return _sportNameDictionary[sportId];
    };
    this.getMarketPageName = function (marketPageId) {
        return _marketPageNameDictionary[marketPageId];
    };
}

function __Module_SportMarket(refreshRate) {
    var _self = this;
    var _TemplateName = 'sport-market/sport-market';
    var _self = this;
    var _template = null;
    var _cache = new __Cache_SportMarket();
    var _hidden = false;
    var _syn = {
        waitingTemplate: false,
        drawing: false,
        refreshRate: refreshRate,
        refreshCount: 0,
        selectedTab: 'sports',
        isInit: true,
        showing: true
    };
    this.getNewMarketPageId = function (sportId, currentMarketPageId) {
        var marketPageCountArray = _cache.getSportMarketPageCount(sportId);
        if (!marketPageCountArray) return;
        c = marketPageCountArray.length;
        var newMarketPageId = 0;
        for (var i = 0; i < c; ++i) {
            var marketPageCount = marketPageCountArray[i];
            var marketPageId = marketPageCount[0];
            var marketPageCount = marketPageCountArray[i];
            if (marketPageCount > 0) {
                if (marketPageId == currentMarketPageId) {
                    return currentMarketPageId;
                } else if (newMarketPageId) {
                    newMarketPageId = marketPageId;
                }
            }
        }
        if (newMarketPageId) {
            return newMarketPageId;
        } else {
            return 1;
        }
    };
    this.initiate = function () {
        TiLib.Timer.addToSecondTimer(_self);
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_syn.waitingTemplate) {
                    if (_template) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                }
            }
        }
    };
    this.onIdle = function (data) {
        _syn.drawing = false;
    };
    this.onUpdate = function (data) {
        if (!data) return;
        _cache.update(data);
        _draw();
        _syn.drawing = false;
        if ($M('slider-bar') && $M('slider-bar').onUpdate) {
            $M('slider-bar').onUpdate();
        }
        _syn.isInit = false;
    };

    function _submit() {
        var sb = [];
        sb.push('sport-market/sport-market-data.aspx');
        if (_syn.isInit) {
            sb.push('?action=init');
        }
        return TiLib.Ajax.sendRequest('sport-market', sb.join(''));
    }
    this.refresh = function (clearAll) {
        if (clearAll) {
            _submit();
        } else {
            _draw();
        }
    }
    this.onTime = function () {
        if (_syn.refreshCount > 0) {
            _syn.refreshCount--;
        } else {
            _syn.refreshCount = _syn.refreshRate;
            _syn.drawing = true;
            _submit();
        }
    };
    this.onSettingChanged = function () {
        var names = CookieHelper.getNames('od-param-');
        var c = names.length;
        for (var i = 0; i < c; ++i) {
            var value = CookieHelper.getValue(names[i]);
            if (value && value !== null) {
                var key = names[i].substring('od-param-'.length);
                switch (key) {
                case 'market-page':
                    var marketId = 1;
                    if (value == 13) {
                        marketId = 7;
                    }
                    $M('odds-display').setDisplaySetting('market-page', marketId);
                    _draw();
                    break;
                }
            }
        }
    };
    this.onClick = function (event) {
        if (!event) event = window.event;
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    };

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'sm') {
                switch (atom[2]) {
                case 'sports':
                case 'markets':
                    _switchTab(atom[2]);
                    return false;
                case 'sport':
                    if (count >= 4) {
                        _switchSport(atom[3]);
                    }
                    return false;
                case 'market':
                    if (count >= 4) {
                        _switchMarket(parseInt(atom[3]));
                    }
                    return false;
                }
            }
        }
        return true;
    }
    this.switchSport = function (selectedSportId) {
        _switchSport(selectedSportId);
    };

    function _switchSport(selectedSportId) {
        var prevSportId = $M('odds-display').getDisplaySetting('sport');
        $M('odds-display').setDisplaySetting('sport', selectedSportId);
        if (selectedSportId != prevSportId) {
            _autoSelectMarketWithOdds()
        }
        if (_syn.selectedTab == 'sports') {
            _switchTab('markets');
        }
        if ($M('slider-bar') && $M('slider-bar').draw) {
            $M('slider-bar').draw();
        }
        if ($M('odds-display-setting') && $M('odds-display-setting').draw) {
            $M('odds-display-setting').draw();
        }
        _draw();
    };
    this.switchMarket = function (selectedMarketId) {
        _switchMarket(selectedMarketId);
    };

    function _switchMarket(selectedMarket) {
        var marketId = parseInt(selectedMarket);
        $M('odds-display').setDisplaySetting('market-page', marketId);
        if ($M('slider-bar') && $M('slider-bar').draw) {
            $M('slider-bar').draw();
        }
        if ($M('odds-display-setting') && $M('odds-display-setting').draw) {
            $M('odds-display-setting').draw();
        }
        _draw();
    };
    this.getTotalParlayCount = function () {
        return _cache.getTotalParlayCount();
    };

    function _switchTab(tabName) {
        if (tabName == _syn.selectedTab) {
            _syn.showing = !_syn.showing;
        } else {
            _syn.showing = true;
            tabName == _syn.selectedTab
        }
        _syn.selectedTab = tabName;
        if (_syn.showing) {
            if ($M('ticket').hideTicket) {
                $M('ticket').hideTicket();
            }
        }
        _draw();
    }

    function _autoSelectMarketWithOdds() {
        var selectedSportId = $M('odds-display').getDisplaySetting('sport');
        var cache = _cache;
        var marketPageCountArray = cache.getSportMarketPageCount(selectedSportId);
        if (!marketPageCountArray) return;
        c = marketPageCountArray.length;
        var marketPageItems = [];
        var totalParlayCount = _cache.getTotalParlayCount();
        for (var i = 1; i < c; ++i) {
            var marketPageCount = marketPageCountArray[i];
            var marketPageId = marketPageCount[0];
            var marketPageEventCount = marketPageCount[1];
            if (marketPageEventCount > 0) {
                $M('odds-display').setDisplaySetting('market-page', marketPageId);
                break;
            }
        }
    }
    this.getCache = function () {
        return _cache;
    };
    this.hideSportMarket = function () {
        _syn.showing = false;
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var template = _template;
        var cache = _cache;
        var d = {};
        d['sports-selected'] = (_syn.selectedTab == 'sports') ? 'selected' : null;
        d['markets-selected'] = (_syn.selectedTab == 'markets') ? 'selected' : null;
        d['sports-hide'] = (!_syn.showing || _syn.selectedTab != 'sports') ? 'hide' : null;
        d['markets-hide'] = (!_syn.showing || _syn.selectedTab != 'markets') ? 'hide' : null;
        var selectedSportId = $M('odds-display').getDisplaySetting('sport');
        var selectedMarketPageId = $M('odds-display').getDisplaySetting('market-page');
        var sportArray = cache.getSportArray();
        var c = sportArray.length;
        var sportItems = [];
        var hasLive = false;
        var selectedSportName = ''
        for (var i = 0; i < c; ++i) {
            var sport = sportArray[i];
            var sportId = sport[0];
            var sportName = cache.getSportName(sportId);
            var sportEventCount = sport[2];
            if (sportEventCount <= 0) continue;
            hasLive = false;
            var marketPageCount = cache.getSportMarketPageCount(sportId);
            if (marketPageCount) {
                for (var j = 0; j < marketPageCount.length; j++) {
                    if (marketPageCount[j][1] > 0 && marketPageCount[j][2] == 1) {
                        hasLive = true;
                        break;
                    }
                }
            }
            d['sport-id'] = sportId;
            d['sport'] = sportName;
            d['sport-count'] = sportEventCount;
            d['sport-selected'] = sportId == selectedSportId ? 'selected' : null;
            if (sportId == selectedSportId) {
                selectedSportName = sportName;
            }
            d['live'] = hasLive ? 'live' : '';
            sportItems.push(template['item-sport'].getText(d));
        }
        if (sportItems.length == 0) {
            var sport = sportArray[0];
            if (sport) {
                var sportId = sport[0];
                var sportName = cache.getSportName(sportId);
                var sportEventCount = sport[2];
                d['sport-id'] = sportId;
                d['sport'] = sportName;
                d['sport-count'] = sportEventCount;
                d['sport-selected'] = sportId == selectedSportId ? 'selected' : null;
                selectedSportName = sportName;
                sportItems.push(template['item-sport'].getText(d));
                selectedSportId = sportId;
                $M('odds-display').setDisplaySetting('sport', sportId);
            }
        }
        d['sport-items'] = sportItems.join('');
        var marketPageCountArray = cache.getSportMarketPageCount(selectedSportId);
        if (!marketPageCountArray) return;
        c = marketPageCountArray.length;
        var marketPageItems = [];
        var totalParlayCount = _cache.getTotalParlayCount();
        for (var i = 0; i < c; ++i) {
            var marketPageCount = marketPageCountArray[i];
            var marketPageId = marketPageCount[0];
            var marketPageEventCount = marketPageCount[1];
            var marketPage = cache.getMarketPage(marketPageId);
            var marketPageName = cache.getMarketPageName(marketPageId);
            if (marketPageId == 13) {
                continue;
            }
            if (marketPageId == 3 && marketPageEventCount == 0) {
                continue;
            }
            d['market-page-id'] = marketPageId;
            d['market-page'] = marketPageName;
            d['market-page-count'] = marketPageEventCount;
            d['market-page-selected'] = marketPageId == selectedMarketPageId ? 'selected' : null;
            d['live'] = (marketPageCount[2] > 0 && marketPageEventCount > 0) ? 'live' : '';
            d['sport-name'] = selectedSportName;
            marketPageItems.push(template['item-market-page'].getText(d));
        }
        d['market-page-items'] = marketPageItems.join('');
        var div = document.getElementById('module-sport-market');
        if (div) {
            div.innerHTML = _template['sport-market'].getText(d);
        }
        if ($M('slider-bar') && $M('slider-bar').onUpdate) {
            $M('slider-bar').onUpdate();
        }
        if ($M('global') && $M('global').redrawLeftColumn) {
            $M('global').redrawLeftColumn();
        }
    };
}

function __Cache_Favourite() {
    var _sportIdDictionary = {};
    var _tournamentIdDictionary = {};
    var _eventResultIdDictionary = {};
    var _sportCountDictionary = {};
    var _sportsName = [];
    var _sportIdArray = [];
    var _tournamentIdArray = [];
    var _eventResultIdArray = [];
    var _updatedTournamentIdArray = null;
    var _updatedEventResultIdArray = null;
    this.update = function (data) {
        var isChanged = false;
        var newSportIdDictionary = {};
        var newEventResultIdDictionary = {};
        var newTournamentIdDictionary = {};
        var newSportIdArray = [];
        var newEventResultIdArray = [];
        var newTournamentIdArray = [];
        var newUpdateTournamentIdArray = [];
        var newUpdateEventResultIdArray = [];
        if (data) {
            if (data[0]) {
                newSportIdArray = data[0];
                var c = newSportIdArray.length;
                for (var i = 0; i < c; ++i) {
                    newSportIdDictionary[newSportIdArray[i]] = 1;
                }
                newsportIdArray = data[0];
            }
            if (data[1]) {
                newTournamentIdArray = data[1];
                c = newTournamentIdArray.length;
                for (i = 0; i < c; ++i) {
                    newTournamentIdDictionary[newTournamentIdArray[i]] = 1;
                }
            }
            if (data[2]) {
                newEventResultIdArray = data[2];
                c = newEventResultIdArray.length;
                for (i = 0; i < c; ++i) {
                    newEventResultIdDictionary[newEventResultIdArray[i]] = 1;
                }
            }
            if (data[3]) {
                _sportCountDictionary = data[3];
            }
            if (data[4] && data[4].length > 0) {
                _sportsName = data[4];
            }
        }
        if (_checkChanges(_sportIdDictionary, newSportIdArray)) {
            isChanged = true;
        }
        if (_checkChanges(newSportIdDictionary, _sportIdArray)) {
            isChanged = true;
        }
        if (_checkChanges(_tournamentIdDictionary, newTournamentIdArray, newUpdateTournamentIdArray)) {
            isChanged = true;
        }
        if (_checkChanges(newTournamentIdDictionary, _tournamentIdArray, newUpdateTournamentIdArray)) {
            isChanged = true;
        }
        if (_checkChanges(_eventResultIdDictionary, newEventResultIdArray, newUpdateEventResultIdArray)) {
            isChanged = true;
        }
        if (_checkChanges(newEventResultIdDictionary, _eventResultIdArray, newUpdateEventResultIdArray)) {
            isChanged = true;
        }
        _sportIdDictionary = newSportIdDictionary;
        _tournamentIdDictionary = newTournamentIdDictionary;
        _eventResultIdDictionary = newEventResultIdDictionary;
        _sportIdArray = newSportIdArray;
        _tournamentIdArray = newTournamentIdArray;
        _eventResultIdArray = newEventResultIdArray;
        _updatedTournamentIdArray = (newUpdateTournamentIdArray.length > 0) ? newUpdateTournamentIdArray : null;
        _updatedEventResultIdArray = (newUpdateEventResultIdArray.length > 0) ? newUpdateEventResultIdArray : null;
        return isChanged;
    };

    function _checkChanges(dictionary, array, updated) {
        var changed = false;
        var c = array.length;
        for (i = 0; i < c; ++i) {
            if (!dictionary[array[i]]) {
                changed = true;
                if (updated) {
                    updated.push(array[i]);
                } else {
                    break;
                }
            }
        }
        return changed;
    };
    this.getSports = function () {
        return _sportIdArray;
    };
    this.hasSport = function (sportId) {
        for (var i = 0; i < _sportIdArray.length; i++) {
            if (_sportIdArray[i] == sportId) {
                return true;
            }
        }
        return false;
    };
    this.getSportsName = function () {
        var sportName = {};
        for (var i = 0; i < _sportIdArray.length; i++) {
            sportName[_sportIdArray[i]] = _sportsName[i];
        }
        return sportName;
    };
    this.hasTournament = function (tournamentId) {
        return _tournamentIdDictionary[tournamentId] ? true : false;
    };
    this.hasEventResult = function (eventResultId) {
        return _eventResultIdDictionary[eventResultId] ? true : false;
    };
    this.hasAllEventResults = function (eventResultIds) {
        if (eventResultIds) {
            var c = eventResultIds.length;
            if (c > 0) {
                for (var i = 0; i < c; ++i) {
                    if (!_eventResultIdDictionary[eventResultIds[i]]) {
                        return false;
                    }
                }
                return true;
            }
        }
        return false;
    };
    this.getTournamentIds = function (tagEventResultArray) {
        var ids = [];
        var c = tagEventResultArray.length;
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResultArray[i];
            var tournament = tagEventResult[1];
            var tournamentId = tournament[0];
            if (_tournamentIdDictionary[tournamentId]) {
                ids.push(tournamentId);
            }
        }
        return ids;
    };
    this.getEventResultIds = function (tagEventResultArray) {
        var ids = [];
        var c = tagEventResultArray.length;
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResultArray[i];
            var eventResultId = tagEventResult[0];
            if (_eventResultIdDictionary[eventResultId]) {
                ids.push(eventResultId);
            }
        }
        return ids;
    };
    this.getUpdatedTournamentIds = function () {
        return _updatedTournamentIdArray;
    };
    this.getUpdatedEventResultIds = function () {
        return _updatedEventResultIdArray;
    };
    this.getSportsCountDictionary = function () {
        return _sportCountDictionary;
    }
    this.isEmpty = function () {
        return _eventResultIdArray.length == 0;
    }
}

function __Module_Favourite() {
    var _self = this;
    var _TemplateName = 'left-column/favourite';
    var _self = this;
    var _template = null;
    var _cache = new __Cache_Favourite();
    var _selectedSportId = 0;
    var _syn = {
        waitingTemplate: false,
        drawing: false,
        refreshCount: 0,
        refreshRate: 60,
        isInit: false,
        showing: true
    };
    this.initiate = function () {
        TiLib.Timer.addToSecondTimer(_self);
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_syn.waitingTemplate) {
                    if (_template) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                }
            }
        }
    };
    this.onUpdate = function (data, refreshCache) {
        if (!data) return;
        var marketPage = $M('odds-display').getDisplaySetting('market-page');
        if (_cache.update(data)) {
            if (refreshCache && marketPage == 13) {
                $M('odds-display').refresh(true);
            } else {
                $M('odds-display').draw();
            }
            $M('sport-market').refresh(true);
            if ($M('slider-bar') && $M('slider-bar').onUpdate) {
                $M('slider-bar').onUpdate();
            }
        }
        _draw();
        _syn.drawing = false;
    };
    this.onTime = function () {
        if (_syn.refreshCount > 0) {
            _syn.refreshCount--;
        } else {
            _syn.refreshCount = _syn.refreshRate;
            _syn.drawing = true;
            _submit();
        }
    };

    function _submit() {
        var sbReq = [];
        sbReq.push('odds-display/action-data.aspx?od-param=');
        sbReq.push($M('odds-display').getOddsDisplayParam());
        sbReq.push('&type=favourite&');
        return TiLib.Ajax.sendRequest('favourite', sbReq.join(''));
    }
    this.addRemoveFavourite = function (action, id, tournamentId) {
        return _addRemoveFavourite(action, id, tournamentId);
    }

    function _addRemoveFavourite(action, id, tournamentId) {
        var sb = [];
        switch (action) {
        case 'add-tournament':
            if (id) {
                sb.push(action);
                sb.push('=');
                sb.push(id.join(','));
                if (tournamentId) {
                    sb.push('&tournament-id=');
                    sb.push(tournamentId);
                }
            }
            break;
        case 'add-event':
        case 'remove-tournament':
        case 'remove-event':
            if (id) {
                sb.push(action);
                sb.push('=');
                sb.push(id);
            }
            break;
        case 'remove-all-live':
            var ids = _cache.getTournamentIds(_liveCache.getTagEventResultArray());
            if (ids && ids.length > 0) {
                sb.push('remove-tournament');
                sb.push('=');
                sb.push(ids.join(','));
            }
            ids = _cache.getEventResultIds(_liveCache.getTagEventResultArray());
            if (ids && ids.length > 0) {
                if (sb.length > 0) {
                    sb.push('&');
                }
                sb.push('remove-event');
                sb.push('=');
                sb.push(ids.join(','));
            }
            break;
        case 'remove-all-nonlive':
            ids = _cache.getTournamentIds(_nonliveCache.getTagEventResultArray());
            if (ids && ids.length > 0) {
                sb.push('remove-tournament');
                sb.push('=');
                sb.push(ids.join(','));
            }
            ids = _cache.getEventResultIds(_nonliveCache.getTagEventResultArray());
            if (ids && ids.length > 0) {
                if (sb.length > 0) {
                    sb.push('&');
                }
                sb.push('remove-event');
                sb.push('=');
                sb.push(ids.join(','));
            }
            break;
        }
        if (sb.length > 0) {
            var sbReq = [];
            sbReq.push('odds-display/action-data.aspx?od-param=');
            sbReq.push($M('odds-display').getOddsDisplayParam());
            sbReq.push('&type=favourite&');
            sbReq.push(sb.join(''));
            return TiLib.Ajax.sendRequest('favourite', sbReq.join(''));
        }
    }
    this.onClick = function (event) {
        if (!event) event = window.event;
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    };

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'sm') {
                switch (atom[2]) {
                case 'sport':
                    if (count >= 4) {
                        _selectedSportId = parseInt(atom[3]);
                        _showFavourite();
                        _draw();
                        if ($M('global') && $M('global').incGA) {
                            $M('global').incGA('favourite', 'left');
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }

    function _showFavourite() {
        $M('odds-display').setDisplaySetting('market-showing', 2);
        if ($M('odds-display').getDisplaySetting('sport') == _selectedSportId) {
            if ($M('odds-display').getDisplaySetting('market-page') == 13) {
                $M('odds-display').refresh(true);
            } else {
                $M('odds-display').setDisplaySetting('market-page', 13);
            }
        } else {
            $M('odds-display').setDisplayParam('market-page', 13);
            $M('odds-display').setDisplaySetting('sport-favourite', _selectedSportId);
        }
    }
    this.getCache = function () {
        return _cache;
    };
    this.draw = function (data) {
        _draw();
    };

    function _draw() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var template = _template;
        var cache = _cache;
        var d = {};
        var count = _populateFavouriteMenu(d);
        var div = document.getElementById('module-favourite');
        if (div) {
            div.innerHTML = d['favourite'];
        }
    };

    function _populateFavouriteMenu(d) {
        var cache = _cache;
        var template = _template;
        var sportsCount = cache.getSportsCountDictionary();
        var sportsName = cache.getSportsName();
        var sports = cache.getSports();
        var c = sports.length;
        var sb = [];
        for (var i = 0; i < c; i++) {
            var sportId = sports[i];
            var sportCount = sportsCount[sportId];
            if (!sportCount) continue;
            d['sport-id'] = sportId;
            d['sport-count'] = sportsCount[sportId];
            d['sport'] = sportsName[sportId];
            d['sport-selected'] = '';
            if (_selectedSportId == sportId) {
                var marketPage = $M('odds-display').getDisplaySetting('market-page');
                if (marketPage == 13) {
                    d['sport-selected'] = 'selected';
                }
            }
            sb.push(template['item-sport'].getText(d));
        }
        if (sb.length > 0 && !cache.isEmpty()) {
            d['sport-items'] = sb.join('');
            d['favourite'] = template['favourite'].getText(d);
        } else {
            d['favourite'] = template['favourite-empty'].getText();
        }
        return sb.length;
    }
}

function __Cache_Event(sortType) {
    var _sortType = sortType;
    var _tournamentDictionary = {};
    var _eventDictionary = {};
    var _eventResultDictionary = {};
    var _eventResultExtraDictionary = {};
    var _oddsDictionary = {};
    var _marketGroupDictionary = {};
    var _tagEventResultArray = [];
    var _oddsCountByEventResult = {};
    var _eventResultIdsByTournament = {};
    var _priceAdjustIndicators = null;
    var _scoreAdjustIndicators = null;
    var _liveStartTimes = null;
    var _sportName = null;
    this.update = function (clearAll, data, priceStyle) {
        var isChanged = false;
        _priceAdjustIndicators = null;
        _scoreAdjustIndicators = null;
        if (clearAll) {
            isChanged = true;
            _tournamentDictionary = {};
            _eventDictionary = {};
            _eventResultDictionary = {};
            _oddsDictionary = {};
            _marketGroupDictionary = {};
        }
        if (data) {
            if (data[0]) {
                isChanged = true;
                _updateElements(_tournamentDictionary, data[0]);
            }
            if (data[1]) {
                isChanged = true;
                _updateElements(_eventDictionary, data[1]);
            }
            if (data[2]) {
                isChanged = true;
                _updateEventResults(_eventResultDictionary, data[2]);
            }
            if (data[3]) {
                isChanged = true;
                _updateEventResultExtras(_eventResultExtraDictionary, data[3]);
            }
            if (data[4]) {
                isChanged = true;
                _deleteElements(_eventResultDictionary, data[4]);
            }
            if (data[5]) {
                isChanged = true;
                _updateOdds(_oddsDictionary, data[5], priceStyle);
            }
            if (data[6]) {
                isChanged = true;
                _deleteElements(_oddsDictionary, data[6]);
            }
            if (data[7]) {
                isChanged = true;
                _updateElements(_marketGroupDictionary, data[7]);
            }
            if (data[8]) {
                isChanged = true;
                _sportName = data[8];
            }
        }
        _normalize();
        return isChanged;
    };
    this.sort = function (sortType) {
        _sortType = sortType;
        _normalize();
    };
    this.hasScoreChange = function () {
        return _scoreAdjustIndicators ? true : false;
    };
    this.hasTV = function () {
        var c = _tagEventResultArray.length;
        for (var i = 0; i < c; ++i) {
            var tag = _tagEventResultArray[i];
            var event = tag[2];
            if (event[9] && event[9] != '') {
                return true;
            }
        }
        return false;
    };
    this.hasMarketGroup = function () {
        var c = _tagEventResultArray.length;
        for (var i = 0; i < c; ++i) {
            var tag = _tagEventResultArray[i];
            if (tag[6] && tag[6][0]) {
                return true;
            }
        }
        return false;
    };
    this.hasTournaments = function (tournamentIds) {
        if (tournamentIds) {
            var ic = _tagEventResultArray.length;
            var jc = tournamentIds.length;
            for (var i = 0; i < ic; ++i) {
                var tournament = _tagEventResultArray[i][1];
                for (var j = 0; j < jc; ++j) {
                    if (tournament[0] == tournamentIds[j]) {
                        return true;
                    }
                }
            }
        }
        return false;
    };
    this.hasEvents = function (eventIds) {
        if (eventIds) {
            var ic = _tagEventResultArray.length;
            var jc = eventIds.length;
            for (var i = 0; i < ic; ++i) {
                var event = _tagEventResultArray[i][2];
                for (var j = 0; j < jc; ++j) {
                    if (event[0] == eventIds[j]) {
                        return true;
                    }
                }
            }
        }
        return false;
    };
    this.hasEventResults = function (eventResultIds) {
        if (eventResultIds) {
            var ic = _tagEventResultArray.length;
            var jc = eventResultIds.length;
            for (var i = 0; i < ic; ++i) {
                var eventResult = _tagEventResultArray[i][3];
                for (var j = 0; j < jc; ++j) {
                    if (eventResult[0] == eventResultIds[j]) {
                        return true;
                    }
                }
            }
        }
        return false;
    };
    this.getEventResultIdsByTournament = function (tournamentId) {
        return _eventResultIdsByTournament[tournamentId];
    };
    this.getTagEventResultArray = function () {
        return _tagEventResultArray;
    };
    this.isEmpty = function () {
        return _tagEventResultArray.length > 0 ? false : true;
    };
    this.getEventMoreOddsCount = function (eventResultId) {
        var eventResult = _eventResultDictionary[eventResultId];
        if (eventResult) {
            var eventId = eventResult[1];
            var event = _eventDictionary[eventId];
            if (event) {
                var count = _oddsCountByEventResult[eventResultId];
                return event[10] - (count ? count : 0);
            }
        }
        return 0;
    };
    this.getEventResultMoreOddsCount = function (eventResultId) {
        var eventResult = _eventResultDictionary[eventResultId];
        if (eventResult) {
            var count = _oddsCountByEventResult[eventResultId];
            return eventResult[5] - (count ? count : 0);
        }
        return 0;
    };
    this.getPriceAdjustIndicators = function (oddsId) {
        return (_priceAdjustIndicators && _priceAdjustIndicators[oddsId]) ? _priceAdjustIndicators[oddsId] : [];
    };
    this.isScoreChanged = function (eventResultId) {
        return (_scoreAdjustIndicators && _scoreAdjustIndicators[eventResultId]) ? true : false;
    };
    this.getLiveStartTime = function (eventResultId) {
        return _liveStartTimes ? _liveStartTimes[eventResultId] : null;
    };
    this.clearAdjustIndicators = function () {
        if (_priceAdjustIndicators || _scoreAdjustIndicators) {
            _priceAdjustIndicators = null;
            _scoreAdjustIndicators = null;
            return true;
        } else {
            return false;
        }
    };
    this.getSportName = function () {
        return _sportName;
    }

    function _updateElements(elementDictionary, elementArray) {
        if (!elementArray) return;
        var c = elementArray.length;
        for (var i = 0; i < c; ++i) {
            var element = elementArray[i];
            if (!element) continue;
            var elementId = element[0];
            var oldElement = elementDictionary[elementId];
            if (oldElement) {
                element = oldElement.updateArray(element);
            }
            elementDictionary[elementId] = element;
        }
    }

    function _deleteElements(elementDictionary, elementIdArray) {
        if (!elementIdArray) return;
        var c = elementIdArray.length;
        for (var i = 0; i < c; ++i) {
            var elementId = elementIdArray[i];
            if (!elementId) continue;
            delete elementDictionary[elementId];
        }
    }

    function _updateEventResults(eventResultDictionary, eventResultArray) {
        if (!eventResultArray) return;
        var c = eventResultArray.length;
        for (var i = 0; i < c; ++i) {
            var eventResult = eventResultArray[i];
            if (!eventResult) continue;
            var eventResultId = eventResult[0];
            var oldEventResult = eventResultDictionary[eventResultId];
            if (oldEventResult) {
                eventResult = oldEventResult.updateArray(eventResult);
                if (eventResult[3] != oldEventResult[3] || eventResult[4] != oldEventResult[4]) {
                    if (!_scoreAdjustIndicators) {
                        _scoreAdjustIndicators = {};
                    }
                    _scoreAdjustIndicators[eventResultId] = true;
                }
            }
            eventResultDictionary[eventResultId] = eventResult;
        }
    }

    function _updateEventResultExtras(eventResultExtraDictionary, eventResultExtraArray) {
        if (!eventResultExtraArray) return;
        var c = eventResultExtraArray.length;
        for (var i = 0; i < c; ++i) {
            var eventResultExtra = eventResultExtraArray[i];
            if (!eventResultExtra) continue;
            var eventResultId = eventResultExtra[0];
            var oldEventResultExtra = eventResultExtraDictionary[eventResultId];
            if (oldEventResultExtra) {
                eventResultExtra = oldEventResultExtra.updateArray(eventResultExtra);
            }
            if (!_liveStartTimes) {
                _liveStartTimes = {};
            }
            _liveStartTimes[eventResultId] = new Date();
            eventResultExtraDictionary[eventResultId] = eventResultExtra;
        }
    }

    function _updateOdds(oddsDictionary, oddsArray, priceStyle) {
        if (!oddsArray) return;
        var c = oddsArray.length;
        for (var i = 0; i < c; ++i) {
            var odds = oddsArray[i];
            if (!odds) continue;
            var oddsId = odds[0];
            var oldOdds = oddsDictionary[oddsId];
            if (oldOdds) {
                odds = oldOdds.updateArray(odds);
                var oldPrices = oldOdds[2];
                var newPrices = odds[2];
                var priceCount = newPrices.length;
                for (var priceIndex = 0; priceIndex < priceCount; ++priceIndex) {
                    var indicator = 0;
                    var oldPrice = oldPrices[priceIndex];
                    var newPrice = newPrices[priceIndex];
                    if (oldPrice == newPrice) continue;
                    if (priceStyle == 3) {
                        indicator = (newPrice > oldPrice) ? 1 : -1;
                    } else {
                        if (oldPrice > 0) {
                            if (newPrice > 0) {
                                indicator = (newPrice > oldPrice) ? 1 : -1;
                            } else {
                                indicator = 1;
                            }
                        } else if (oldPrice < 0) {
                            if (newPrice > 0) {
                                indicator = -1;
                            } else {
                                indicator = (newPrice > oldPrice) ? 1 : -1;
                            }
                        } else {
                            indicator = 0;
                        }
                    }
                    if (indicator != 0) {
                        if (!_priceAdjustIndicators) {
                            _priceAdjustIndicators = {};
                        }
                        var indicators = _priceAdjustIndicators[oddsId];
                        if (!indicators) {
                            indicators = [];
                            _priceAdjustIndicators[oddsId] = indicators;
                        }
                        indicators[priceIndex] = indicator;
                    }
                }
            }
            oddsDictionary[oddsId] = odds;
        }
    }

    function _normalize() {
        _oddsCountByEventResult = {};
        var oddsByEventResultId = {};
        for (var oddsId in _oddsDictionary) {
            var odds = _oddsDictionary[oddsId];
            var eventResultId = odds[1][0];
            var eventResult = _eventResultDictionary[eventResultId];
            if (!eventResult) {
                delete _oddsDictionary[oddsId];
                continue;
            }
            var eventId = eventResult[1];
            _oddsCountByEventResult[eventResultId] = _oddsCountByEventResult[eventResultId] ? (_oddsCountByEventResult[eventResultId] + 1) : 1;
            var marketDisplayId = odds[1][1];
            var oddsByMarketDisplayId = oddsByEventResultId[eventResultId];
            if (!oddsByMarketDisplayId) {
                oddsByMarketDisplayId = {};
                oddsByEventResultId[eventResultId] = oddsByMarketDisplayId;
            }
            oddsArray = oddsByMarketDisplayId[marketDisplayId];
            if (!oddsArray) {
                oddsArray = [];
                oddsByMarketDisplayId[marketDisplayId] = oddsArray;
            }
            oddsArray.push(odds);
        }
        for (eventResultId in oddsByEventResultId) {
            oddsByMarketDisplayId = oddsByEventResultId[eventResultId];
            for (marketDisplayId in oddsByMarketDisplayId) {
                oddsArray = oddsByMarketDisplayId[marketDisplayId];
                oddsArray.sort(_sortOddsCallback);
            }
        }
        var normalizedMarketGroupDiciionary = {};
        for (var marketGroupId in _marketGroupDictionary) {
            var marketGroup = _marketGroupDictionary[marketGroupId];
            var normalizedMarketGroup = marketGroup.updateArray(marketGroup, []);
            normalizedMarketGroup[2] = TiLib.Template.createTemplate(normalizedMarketGroup[2]);
            normalizedMarketGroup[3] = TiLib.Template.createTemplate(normalizedMarketGroup[3]);
            normalizedMarketGroupDiciionary[marketGroupId] = normalizedMarketGroup;
        }
        _tagEventResultArray = [];
        _eventResultIdsByTournament = {};
        var deletedEventResultIds = [];
        for (eventResultId in _eventResultDictionary) {
            eventResultId = parseInt(eventResultId);
            if (isNaN(eventResultId)) continue;
            eventResult = _eventResultDictionary[eventResultId];
            if (!eventResult) continue;
            var eventResultExtra = _eventResultExtraDictionary[eventResultId];
            oddsByMarketDisplayId = oddsByEventResultId[eventResultId];
            var frozenOdds = eventResultExtra ? eventResultExtra[8] : null;
            var marketGroupId = eventResult[2];
            if (!oddsByMarketDisplayId && (!eventResultExtra || !eventResultExtra[1] || !frozenOdds)) {
                deletedEventResultIds.push(eventResultId);
                continue;
            }
            eventId = eventResult[1];
            var event = _eventDictionary[eventId];
            var tournamentId = event[2];
            var tournament = _tournamentDictionary[tournamentId];
            if (!tournament) continue;
            var eventResultIds = _eventResultIdsByTournament[tournamentId];
            if (!eventResultIds) {
                eventResultIds = [];
                _eventResultIdsByTournament[tournamentId] = eventResultIds;
            }
            eventResultIds.push(eventResultId);
            marketGroup = normalizedMarketGroupDiciionary[marketGroupId];
            if (oddsByMarketDisplayId || (eventResultExtra && eventResultExtra[1] && frozenOdds)) {
                var tagEventResult = [eventResultId, tournament, event, eventResult, eventResultExtra, oddsByMarketDisplayId, marketGroup, false];
                _tagEventResultArray.push(tagEventResult);
            }
        }
        _tagEventResultArray = _sortTagEventResultArray(_tagEventResultArray);
        var c = deletedEventResultIds.length;
        for (var i = 0; i < c; ++i) {
            eventResultId = deletedEventResultIds[i];
            delete _eventResultDictionary[eventResultId];
        }
    }

    function _sortTagEventResultArray(tagEventResultArray) {
        var sortedTagEventResultArray = [];
        var tournamentId = 0;
        var tagsInTournament = [];
        tagEventResultArray.sort(_sortTagEventResultFirstCallback);
        var c = tagEventResultArray.length;
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResultArray[i];
            var tournament = tagEventResult[1];
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                if (tagsInTournament.length > 0) {
                    tagsInTournament.sort(_sortTagEventResultSecondCallback);
                    sortedTagEventResultArray = sortedTagEventResultArray.concat(tagsInTournament);
                    tagsInTournament = [];
                }
            }
            tagsInTournament.push(tagEventResult);
        }
        if (tagsInTournament.length > 0) {
            tagsInTournament.sort(_sortTagEventResultSecondCallback);
            sortedTagEventResultArray = sortedTagEventResultArray.concat(tagsInTournament);
        }
        return sortedTagEventResultArray;
    }

    function _sortTagEventResultFirstCallback(tagEventResult1, tagEventResult2) {
        var event1 = tagEventResult1[2];
        var event2 = tagEventResult2[2];
        var eventCode1 = event1[5];
        var eventCode2 = event2[5];
        var showtime1 = new Date(event1[7]);
        var showtime2 = new Date(event2[7]);
        if (_sortType == 2) {
            if (showtime1 - showtime2) {
                return (showtime1 < showtime2) ? -1 : 1;
            }
            if (eventCode1 != eventCode2) {
                return (eventCode1 < eventCode2) ? -1 : 1;
            }
        } else {
            if (eventCode1 != eventCode2) {
                return (eventCode1 < eventCode2) ? -1 : 1;
            }
            if (showtime1 - showtime2) {
                return (showtime1 < showtime2) ? -1 : 1;
            }
        }
        var eventId1 = event1[0];
        var eventId2 = event2[0];
        if (eventId1 != eventId2) {
            return eventId1 - eventId2;
        }
        var eventResult1 = tagEventResult1[3];
        var eventResult2 = tagEventResult2[3];
        var eventResultId1 = eventResult1[0];
        var eventresultId2 = eventResult2[0];
        return eventResultId1 - eventresultId2;
    }

    function _sortTagEventResultSecondCallback(tagEventResult1, tagEventResult2) {
        var event1 = tagEventResult1[2];
        var event2 = tagEventResult2[2];
        var marketGroup1 = tagEventResult1[6];
        var marketGroup2 = tagEventResult2[6];
        var marketGroupId1 = marketGroup1 ? marketGroup1[0] : 0;
        var marketGroupId2 = marketGroup2 ? marketGroup2[0] : 0;
        var marketGroupPriority1 = marketGroup1 ? marketGroup1[4] : -1;
        var marketGroupPriority2 = marketGroup2 ? marketGroup2[4] : -1;
        if (marketGroupId1 != marketGroupId2) {
            if (marketGroupPriority1 != marketGroupPriority2) {
                return marketGroupPriority1 - marketGroupPriority2;
            }
            return marketGroupId1 - marketGroupId2;
        }
        var eventCode1 = event1[5];
        var eventCode2 = event2[5];
        var showtime1 = new Date(event1[7]);
        var showtime2 = new Date(event2[7]);
        if (_sortType == 2) {
            if (showtime1 - showtime2) {
                return (showtime1 < showtime2) ? -1 : 1;
            }
            if (eventCode1 != eventCode2) {
                return (eventCode1 < eventCode2) ? -1 : 1;
            }
        } else {
            if (eventCode1 != eventCode2) {
                return (eventCode1 < eventCode2) ? -1 : 1;
            }
            if (showtime1 - showtime2) {
                return (showtime1 < showtime2) ? -1 : 1;
            }
        }
        var eventId1 = event1[0];
        var eventId2 = event2[0];
        if (eventId1 != eventId2) {
            return eventId1 - eventId2;
        }
        var eventResult1 = tagEventResult1[3];
        var eventResult2 = tagEventResult2[3];
        var eventResultId1 = eventResult1[0];
        var eventresultId2 = eventResult2[0];
        return eventResultId1 - eventresultId2;
    }

    function _sortOddsCallback(odds1, odds2) {
        var maxbet1 = odds1[1][3];
        var maxbet2 = odds2[1][3];
        if (maxbet1 != maxbet2) {
            return (maxbet1 > maxbet2) ? -1 : 1;
        }
        return (odds1[0] < odds2[0]) ? -1 : 1;
    }
}

function __Cache_Outright() {
    var _tournamentDictionary = {};
    var _outrightDictionary = {};
    var _tagOutrightDictionary = {};
    var _tagOutrightArray = [];
    var _sportName = null;
    var _priceAdjustIndicators = null;
    this.update = function (clearAll, data) {
        _priceAdjustIndicators = null;
        var isChanged = false;
        if (clearAll) {
            _tournamentDictionary = {};
            _outrightDictionary = {};
            isChanged = true;
        }
        if (data) {
            if (data[0]) {
                _updateElements(_tournamentDictionary, data[0]);
                isChanged = true;
            }
            if (data[1]) {
                _updateOutrights(_outrightDictionary, data[1]);
                isChanged = true;
            }
            if (data[2]) {
                _deleteElements(_outrightDictionary, data[2]);
                isChanged = true;
            }
            if (data[3]) {
                _sportName = data[3];
                isChanged = true;
            }
        }
        _normalize();
        return isChanged;
    };
    this.normalize = function () {
        _normalize();
    };
    this.getTagOutrightArray = function () {
        return _tagOutrightArray;
    };
    this.isEmpty = function () {
        return _tagOutrightArray.length > 0 ? false : true;
    };
    this.getTagOutright = function (outrightId) {
        return _tagOutrightDictionary[outrightId];
    };
    this.getPriceAdjustIndicators = function (outrightId) {
        return (_priceAdjustIndicators && _priceAdjustIndicators[outrightId]) ? _priceAdjustIndicators[outrightId] : 0;
    };
    this.clearAdjustIndicators = function () {
        if (_priceAdjustIndicators) {
            _priceAdjustIndicators = null;
            return true;
        } else {
            return false;
        }
    };
    this.getSportName = function () {
        return _sportName;
    }

    function _updateElements(elementDictionary, elementArray) {
        if (!elementArray) return;
        var c = elementArray.length;
        for (var i = 0; i < c; ++i) {
            var element = elementArray[i];
            if (!element) continue;
            var elementId = element[0];
            var oldElement = elementDictionary[elementId];
            if (oldElement) {
                element = oldElement.updateArray(element);
            }
            elementDictionary[elementId] = element;
        }
    }

    function _deleteElements(elementDictionary, elementIdArray) {
        if (!elementIdArray) return;
        var c = elementIdArray.length;
        for (var i = 0; i < c; ++i) {
            var elementId = elementIdArray[i];
            if (!elementId) continue;
            delete elementDictionary[elementId];
        }
    }

    function _updateOutrights(outrightDictionary, outrightArray) {
        if (!outrightArray) return;
        var c = outrightArray.length;
        for (var i = 0; i < c; ++i) {
            var outright = outrightArray[i];
            if (!outright) continue;
            var outrightId = outright[0];
            var oldOutright = outrightDictionary[outrightId];
            if (oldOutright) {
                outright = oldOutright.updateArray(outright);
                var oldPrice = oldOutright[2];
                var newPrice = outright[2];
                if (oldPrice != newPrice) {
                    var indicator = (newPrice > oldPrice) ? 1 : -1;
                    if (!_priceAdjustIndicators) {
                        _priceAdjustIndicators = {};
                    }
                    _priceAdjustIndicators[outrightId] = indicator;
                }
            }
            outrightDictionary[outrightId] = outright;
        }
    }

    function _normalize() {
        _tagOutrightDictionary = {};
        _tagOutrightArray = [];
        for (outrightId in _outrightDictionary) {
            outrightId = parseInt(outrightId);
            var outright = _outrightDictionary[outrightId];
            if (!outright) continue;
            var tournamentId = outright[4];
            var tournament = _tournamentDictionary[tournamentId];
            var tagOutright = [outrightId, tournament, outright];
            _tagOutrightDictionary[outrightId] = tagOutright;
            _tagOutrightArray.push(tagOutright);
        }
        _tagOutrightArray.sort(_sortTagOutrightCallback);
    }

    function _sortTagOutrightCallback(tagOutright1, tagOutright2) {
        var tournamentCode1 = tagOutright1[1][2];
        var tournamentCode2 = tagOutright2[1][2];
        var tournamentName1 = tagOutright1[1][1];
        var tournamentName2 = tagOutright2[1][1];
        var price1 = tagOutright1[2][2];
        var price2 = tagOutright2[2][2];
        var eventCode1 = tagOutright1[2][6];
        var eventCode2 = tagOutright2[2][6];
        if (tournamentCode1 != tournamentCode2) {
            if (!tournamentCode1) {
                return 1;
            }
            if (!tournamentCode2) {
                return -1;
            }
            return (tournamentCode1 < tournamentCode2) ? -1 : 1;
        }
        if (tournamentName1 && tournamentName1 != tournamentName2) {
            return (tournamentName1 < tournamentName2) ? -1 : 1;
        }
        if (price1 != price2) {
            return (price1 < price2) ? -1 : 1;
        }
        if (eventCode1 && eventCode1 != eventCode2) {
            return (eventCode1 < eventCode2) ? -1 : 1;
        }
        return tagOutright1[0] - tagOutright2[0];
    }
}

function __Cache_Media() {
    var _liveVideoEventIdDictionary = {};
    var _nonliveVideoEventIdDictionary = {};
    var _runningBallEventIdDictionary = {};
    var _liveVideoEventIdArray = [];
    var _nonliveVideoEventIdArray = [];
    var _runningBallEventIdArray = [];
    var _liveCenterCount = 0;
    this.update = function (data) {
        if (!data) {
            return false;
        }
        var isChanged = false;
        var newLiveVideoEventIdDictionary = {};
        var newNonliveVideoEventIdDictionary = {};
        var newRunningBallEventIdDictionary = {};
        var newLiveVideoEventIdArray = (data && data[0]) ? data[0] : _liveVideoEventIdArray;
        var newNonliveVideoEventIdArray = (data && data[1]) ? data[1] : _nonliveVideoEventIdArray;
        var newRunningBallEventIdArray = (data && data[2]) ? data[2] : _runningBallEventIdArray;
        _liveCenterCount = 0;
        var liveEventIds = {};
        var c = newLiveVideoEventIdArray.length;
        for (var i = 0; i < c; ++i) {
            var eventId = newLiveVideoEventIdArray[i];
            newLiveVideoEventIdDictionary[eventId] = 1;
            liveEventIds[eventId] = 1;
        }
        c = newNonliveVideoEventIdArray.length;
        for (i = 0; i < c; ++i) {
            newNonliveVideoEventIdDictionary[newNonliveVideoEventIdArray[i]] = 1;
        }
        c = newRunningBallEventIdArray.length;
        for (i = 0; i < c; ++i) {
            eventId = newRunningBallEventIdArray[i];
            newRunningBallEventIdDictionary[eventId] = 1;
            liveEventIds[eventId] = 1;
        }
        for (i in liveEventIds) {
            ++_liveCenterCount;
        }
        if (_checkChanges(_liveVideoEventIdDictionary, newLiveVideoEventIdDictionary)) {
            isChanged = true;
        }
        if (_checkChanges(_nonliveVideoEventIdDictionary, newNonliveVideoEventIdDictionary)) {
            isChanged = true;
        }
        if (_checkChanges(_runningBallEventIdDictionary, newRunningBallEventIdDictionary)) {
            isChanged = true;
        }
        _liveVideoEventIdDictionary = newLiveVideoEventIdDictionary;
        _nonliveVideoEventIdDictionary = newNonliveVideoEventIdDictionary;
        _runningBallEventIdDictionary = newRunningBallEventIdDictionary;
        _liveVideoEventIdArray = newLiveVideoEventIdArray;
        _nonliveVideoEventIdArray = newNonliveVideoEventIdArray;
        _runningBallEventIdArray = newRunningBallEventIdArray;
        return isChanged;
    };

    function _checkChanges(oldDictionary, newDictionary) {
        for (var key in newDictionary) {
            if (!oldDictionary[key]) {
                return true;
            }
        }
        for (var key in oldDictionary) {
            if (!newDictionary[key]) {
                return true;
            }
        }
        return false;
    };
    this.getLiveCenterCount = function () {
        return _liveCenterCount;
    };
    this.hasLiveCenter = function (eventId) {
        return (_liveVideoEventIdDictionary[eventId] || _runningBallEventIdDictionary[eventId]) ? true : false;
    };
    this.hasLiveVideo = function (eventId) {
        return _liveVideoEventIdDictionary[eventId] ? true : false;
    };
    this.hasNonliveVideo = function (eventId) {
        return _nonliveVideoEventIdDictionary[eventId] ? true : false;
    };
}

function __Cache_SelectTournament() {
    var _self = this;
    var _isNoFilter;
    var _tournamentDictionary = {};
    var _tournamentArray = [];
    this.update = function (data) {
        _isNoFilter = data[0];
        _tournamentArray = data[1];
        _tournamentDictionary = {};
        var c = _tournamentArray.length;
        for (var i = 0; i < c; ++i) {
            var tournament = _tournamentArray[i];
            _tournamentDictionary[tournament[0]] = tournament;
        }
    }
    this.isNoFilter = function () {
        return _isNoFilter;
    };
    this.getTournamentArray = function () {
        return _tournamentArray;
    };
    this.selectTournament = function (tournamentId, selected) {
        _isNoFilter = false;
        var tournament = _tournamentDictionary[tournamentId];
        if (tournament) {
            tournament[2] = selected;
        }
    };
    this.setNoFilter = function (isNoFilter) {
        _self.selectAllTournaments();
        _isNoFilter = isNoFilter;
    };
    this.selectAllTournaments = function () {
        _isNoFilter = false;
        var c = _tournamentArray.length;
        for (var i = 0; i < c; ++i) {
            var tournament = _tournamentArray[i];
            tournament[2] = 1;
        }
    };
    this.deselectAllTournaments = function () {
        _isNoFilter = false;
        var c = _tournamentArray.length;
        for (var i = 0; i < c; ++i) {
            var tournament = _tournamentArray[i];
            tournament[2] = 0;
        }
    };
}

function __OddsUtility() {
    var _self = this;
    var _marketDisplayBetOptions = {
        1: ['h', 'a'],
        2: ['h', 'a'],
        3: ['h', 'a'],
        4: ['00', '01', '02', '03', '04', '10', '11', '12', '13', '14', '20', '21', '22', '23', '24', '30', '31', '32', '33', '34', '40', '41', '42', '43', '44', 'o'],
        5: ['1', 'x', '2'],
        6: ['0-1', '2-3', '4-6', '7-over'],
        7: ['h', 'a'],
        8: ['1', 'x', '2'],
        9: ['h', 'a'],
        10: ['hh', 'hd', 'ha', 'dh', 'dd', 'da', 'ah', 'ad', 'aa'],
        11: ['1', '2'],
        12: ['h', 'a'],
        13: ['hf', 'hl', 'af', 'al', 'ng'],
        14: ['00', '01', '02', '03', '10', '11', '12', '13', '20', '21', '22', '23', '30', '31', '32', '33', 'o'],
        15: ['x2', '12', '1x'],
        16: ['1', 'x', '2'],
        17: ['1', 'x', '2']
    };
    var _marketDisplayTemplateNames = {
        1: 'hdp',
        2: 'oe',
        3: 'ou',
        4: 'cs',
        5: '1x2',
        6: 'tg',
        7: 'fhhdp',
        8: 'fh1x2',
        9: 'fhou',
        10: 'htft',
        11: 'ml',
        12: 'fhoe',
        13: 'fglg',
        14: 'fhcs',
        15: 'dc',
        16: 'ls',
        17: 'fhls'
    };
    var _marketDisplayOptionTemplateNames = {
        'hdp': ['home', 'away'],
        'fhhdp': ['home', 'away'],
        'oe': ['odd', 'even'],
        'fhoe': ['odd', 'even'],
        'ou': ['over', 'under'],
        'fhou': ['over', 'under'],
        'cs': ['00', '01', '02', '03', '04', '10', '11', '12', '13', '14', '20', '21', '22', '23', '24', '30', '31', '32', '33', '34', '40', '41', '42', '43', '44', 'aos'],
        'fhcs': ['00', '01', '02', '03', '10', '11', '12', '13', '20', '21', '22', '23', '30', '31', '32', '33', 'aos'],
        '1x2': ['1', 'x', '2'],
        'fh1x2': ['1', 'x', '2'],
        'ls': ['1', 'x', '2'],
        'fhls': ['1', 'x', '2'],
        'tg': ['01', '23', '46', '7over'],
        'dc': ['x2', '12', '1x'],
        'htft': ['hh', 'hd', 'ha', 'dh', 'dd', 'da', 'ah', 'ad', 'aa'],
        'ml': ['1', '2'],
        'fglg': ['hf', 'hl', 'af', 'al', 'ng']
    };
    var _liveTimerMinuteCap = 99;

    function _getShowTime(showTime, usesLocalTime) {
        var date = TiLib.Date.parseDate(showTime, 'mm/dd/yyyy hh:mm');
        if (!isNaN(date)) {
            if (usesLocalTime && parseInt(usesLocalTime)) {
                var tzd = (8 * 60) + (new Date()).getTimezoneOffset();
                date = new Date(date.getTime() - tzd * 60000);
            }
            return date;
        }
        return NaN;
    };
    this.getTwoDigits = function (number) {
        if (number < 10) {
            return '0' + number;
        } else {
            return number;
        }
    };
    this.getPointString = function (point) {
        var point = parseFloat(point);
        if (point < 0) point = -point;
        var number = TiLib.Number.roundDown(point);
        var fraction = point - number;
        if (fraction > 0) {
            if (fraction < 0.5) {
                return TiLib.Number.toString(number) + '-' + TiLib.Number.toString(number + 0.5, 1);
            } else if (fraction > 0.5) {
                return TiLib.Number.toString(number + 0.5, 1) + '-' + TiLib.Number.toString(number + 1);
            } else {
                return TiLib.Number.toString(point, 2, 2);
            }
        }
        return TiLib.Number.toString(point, 1, 1);
    };
    this.getPointStringWithSign = function (point, side) {
        var point = parseFloat(point);
        if (point == 0) return TiLib.Number.toString(point, 2, 2);;
        var sign = '';
        if (side) {
            sign = point > 0 ? '+' : '-';
        } else {
            sign = point < 0 ? '+' : '-';
        }
        if (point < 0) point = -point;
        return sign + TiLib.Number.toString(point, 2, 2);
    };
    this.getLiveTime = function (period, start, currentMinutes, totalMinutes) {
        var now = new Date();
        var minutes = parseInt((now - start) / 60000 + currentMinutes);
        if (minutes > _liveTimerMinuteCap) {
            minutes = _liveTimerMinuteCap;
        }
        if (period > 2) {
            return (period - 2) + 'E ' + minutes + '\'';
        } else {
            return period + 'H ' + minutes + '\'';
        }
    };
    this.getLiveTimeFull = function (period, start, currentMinutes, totalMinutes) {
        var now = new Date();
        var minutes = parseInt((now - start) / 60000 + currentMinutes);
        if (minutes > _liveTimerMinuteCap) {
            minutes = _liveTimerMinuteCap;
        }
        switch (period) {
        case 1:
            return minutes + '\' ( 1H ' + minutes + '\' )';
        case 2:
            return (45 + minutes) + '\' ( 2H ' + minutes + '\' )';
        case 3:
            return (90 + minutes) + '\' ( 1E ' + minutes + '\' )';
        case 4:
            return (105 + minutes) + '\' ( 2E ' + minutes + '\' )';
        default:
            return 'Live';
        }
    };
    this.populateShowTime = function (d, showTime, usesLocalTimezone) {
        var date = _getShowTime(showTime, usesLocalTimezone);
        if (date) {
            d['showtime-year'] = _self.getTwoDigits(date.getFullYear());
            d['showtime-month'] = _self.getTwoDigits(date.getMonth() + 1);
            d['showtime-day'] = _self.getTwoDigits(date.getDate());
            d['showtime-hour'] = _self.getTwoDigits(date.getHours());
            d['showtime-minute'] = _self.getTwoDigits(date.getMinutes());
        }
    };
    this.populateTournament = function (d, tournament) {
        d['tournament-id'] = tournament[0];
        d['tournament'] = TiLib.Text.encodeHTML(tournament[1]);
    };
    this.populateTournamentInfo = function (d, tournament, tournamentInfoTemplate) {
        if (tournament[3]) {
            d['tournament-info-value'] = TiLib.Text.encodeHTML(tournament[3]);
            d['tournament-info'] = tournamentInfoTemplate.getText(d);
        } else {
            d['tournament-info-value'] = null;
            d['tournament-info'] = null;
        }
    };
    this.populateEvent = function (d, event) {
        d['event-id'] = event[0];
        d['raw-home'] = event[3];
        d['home'] = TiLib.Text.encodeHTML(event[3]);
        d['original-home'] = d['home'];
        d['raw-away'] = event[4];
        d['away'] = TiLib.Text.encodeHTML(event[4]);
        d['original-away'] = d['away'];
        d['tv-channel'] = event[9] ? TiLib.Text.encodeHTML(event[9]) : null;
    };
    this.populateMarketGroup = function (d, marketGroup) {
        d['market-group-id'] = marketGroup[0];
        d['market-group'] = TiLib.Text.encodeHTML(marketGroup[1]);
    };
    this.populateMarketGroupTeams = function (d, marketGroup) {
        d['home'] = d['raw-home'];
        d['away'] = d['raw-away'];
        var home = TiLib.Text.encodeHTML(marketGroup[2].getText(d));
        var away = TiLib.Text.encodeHTML(marketGroup[3].getText(d));
        d['home'] = home;
        d['away'] = away;
    };
    this.populateOddsPoints = function (d, odds, pointDisplayClass, pointHideClass) {
        var marketDisplayId = odds[1][1];
        var marketName = _marketDisplayTemplateNames[marketDisplayId];
        if (!marketName) return;
        var optionNames = _marketDisplayOptionTemplateNames[marketName];
        var point = odds[1][4];
        switch (marketName) {
        case 'hdp':
        case 'fhhdp':
            d['price-' + marketName + '-' + optionNames[0] + '-point'] = point >= 0 ? _self.getPointString(point) : '&#xA0;';
            d['price-' + marketName + '-' + optionNames[1] + '-point'] = point < 0 ? _self.getPointString(point) : '&#xA0;';
            d['price-' + marketName + '-' + optionNames[0] + '-point-sign'] = _self.getPointStringWithSign(point, 0);
            d['price-' + marketName + '-' + optionNames[1] + '-point-sign'] = _self.getPointStringWithSign(point, 1);
            if (pointDisplayClass && pointHideClass) {
                d['price-' + marketName + '-' + optionNames[0] + '-point-class'] = point >= 0 ? pointDisplayClass : pointHideClass;
                d['price-' + marketName + '-' + optionNames[1] + '-point-class'] = point < 0 ? pointDisplayClass : pointHideClass;
            }
            d['price-' + marketName + '-point'] = _self.getPointString(point);
            break;
        case 'ou':
        case 'fhou':
            d['price-' + marketName + '-point'] = _self.getPointString(point);
            break;
        }
    };
    this.clearOddsPoints = function (d, marketDisplayId) {
        var marketName = _marketDisplayTemplateNames[marketDisplayId];
        if (!marketName) return;
        var optionNames = _marketDisplayOptionTemplateNames[marketName];
        switch (marketName) {
        case 'hdp':
        case 'fhhdp':
            d['price-' + marketName + '-' + optionNames[0] + '-point-sign'] = '&#xA0;';
            d['price-' + marketName + '-' + optionNames[1] + '-point-sign'] = '&#xA0;';
            d['price-' + marketName + '-' + optionNames[0] + '-point'] = '&#xA0;';
            d['price-' + marketName + '-' + optionNames[1] + '-point'] = '&#xA0;';
            d['price-' + marketName + '-point'] = '&#xA0;';
            break;
        case 'ou':
        case 'fhou':
            d['price-' + marketName + '-point'] = '&#xA0;';
            d['price-' + marketName + '-' + optionNames[0] + '-point'] = '&#xA0;';
            d['price-' + marketName + '-' + optionNames[1] + '-point'] = '&#xA0;';
            break;
        }
    };
    this.populateOddsLabels = function (d, odds) {
        var marketDisplayId = odds[1][1];
        var marketName = _marketDisplayTemplateNames[marketDisplayId];
        if (!marketName) return;
        var optionNames = _marketDisplayOptionTemplateNames[marketName];
        switch (marketName) {
        case 'ou':
        case 'fhou':
            d['price-' + marketName + '-' + optionNames[0] + '-label'] = 'o';
            d['price-' + marketName + '-' + optionNames[1] + '-label'] = 'u';
            break;
        case 'oe':
        case 'fhoe':
            d['price-' + marketName + '-' + optionNames[0] + '-label'] = 'o';
            d['price-' + marketName + '-' + optionNames[1] + '-label'] = 'e';
            break;
        }
    };
    this.clearOddsLabels = function (d, marketDisplayId) {
        var marketName = _marketDisplayTemplateNames[marketDisplayId];
        if (!marketName) return;
        var optionNames = _marketDisplayOptionTemplateNames[marketName];
        switch (marketName) {
        case 'ou':
        case 'fhou':
            d['price-' + marketName + '-' + optionNames[0] + '-label'] = '&#xA0;';
            d['price-' + marketName + '-' + optionNames[1] + '-label'] = '&#xA0;';
            break;
        case 'oe':
        case 'fhoe':
            d['price-' + marketName + '-' + optionNames[0] + '-label'] = '&#xA0;';
            d['price-' + marketName + '-' + optionNames[1] + '-label'] = '&#xA0;';
            break;
        }
    };
    this.populateOddsIndicators = function (d, odds, priceAdjustIndicators, up, down, oddId) {
        var oddsId = odds[0];
        var marketDisplayId = odds[1][1];
        var marketName = _marketDisplayTemplateNames[marketDisplayId];
        if (!marketName) return;
        var optionNames = _marketDisplayOptionTemplateNames[marketName];
        var betOptions = _marketDisplayBetOptions[marketDisplayId];
        var c = optionNames.length;
        for (var i = 0; i < c; ++i) {
            var prefix = 'price-' + marketName + '-' + optionNames[i] + '-';
            if (priceAdjustIndicators && priceAdjustIndicators[i] && priceAdjustIndicators[i] != -2) {
                d[prefix + 'indicator'] = (priceAdjustIndicators[i] > 0 ? up : down);
            } else {
                d[prefix + 'indicator'] = '&#xA0;';
            }
            if (oddId && (oddId == (oddsId + betOptions[i]) || oddId[oddsId + betOptions[i]])) {
                d[prefix + 'indicator'] += ' odds-selected';
            } else {
                d[prefix + 'indicator'] += ' dummy-more-class';
            }
        }
    };
    this.clearOddsIndicators = function (d, marketDisplayId) {
        var marketName = _marketDisplayTemplateNames[marketDisplayId];
        if (!marketName) return;
        var optionNames = _marketDisplayOptionTemplateNames[marketName];
        var c = optionNames.length;
        for (var i = 0; i < c; ++i) {
            var prefix = 'price-' + marketName + '-' + optionNames[i] + '-';
            d[prefix + 'indicator'] = '&#xA0;';
        }
    };
    this.getPriceText = function (d, odds, priceTextTemplate, index) {
        var oddsId = odds[0];
        var marketDisplayId = odds[1][1];
        var prices = odds[2];
        var marketName = _marketDisplayTemplateNames[marketDisplayId];
        if (!marketName) return null;
        var optionNames = _marketDisplayOptionTemplateNames[marketName];
        var betOptions = _marketDisplayBetOptions[marketDisplayId];
        var price = prices[index];
        if (price) {
            d['odds-id'] = oddsId;
            d['price-value'] = TiLib.Number.toString(price, 3, (marketName == 'cs' || marketName == 'fhcs') ? 0 : 2);
            d['odds-option'] = betOptions[index];
            d['price-text-class'] = price < 0 ? 'red' : 'black';
            return priceTextTemplate.getText(d);
        }
        return null;
    };
    this.populateOdds = function (d, odds, priceTextTemplate, priceAdjustIndicators, forceTwoDecimal, disabledClass, oddId) {
        var oddsId = odds[0];
        var marketDisplayId = odds[1][1];
        var point = odds[1][4];
        var prices = odds[2];
        var marketName = _marketDisplayTemplateNames[marketDisplayId];
        if (!marketName) return;
        var optionNames = _marketDisplayOptionTemplateNames[marketName];
        var betOptions = _marketDisplayBetOptions[marketDisplayId];
        var c = optionNames.length;
        for (var i = 0; i < c; ++i) {
            var prefix = 'price-' + marketName + '-' + optionNames[i] + '-';
            var price = prices[i];
            var oddSelectedClass = '';
            var option = optionNames[i];
            var betOption = betOptions[i];
            if (price) {
                d[prefix + 'odds-id'] = d['odds-id'] = oddsId;
                d[prefix + 'price-value'] = d['price-value'] = TiLib.Number.toString(price, 3, ((marketName == 'cs' || marketName == 'fhcs') && !forceTwoDecimal) ? 0 : 2);
                d[prefix + 'odds-option'] = d['odds-option'] = betOption;
                d['price-text-class'] = price < 0 ? 'red' : 'black';
                if (priceAdjustIndicators && priceAdjustIndicators[i]) {
                    d[prefix + 'cell-class'] = 'odds-change dummy-class';
                } else {
                    d[prefix + 'cell-class'] = 'dummy-class';
                }
                if (oddId && (oddId == (oddsId + betOption) || oddId[oddsId + betOption])) {
                    d[prefix + 'cell-class'] = 'odds-selected';
                }
                d[prefix + 'cursor-class'] = 'cursor-pointer';
                var priceText = priceTextTemplate.getText(d);
                d[prefix + 'text'] = priceText;
                d['price-x-' + i + '-text'] = priceText;
                d['odds-' + marketName + '-' + option + '-cell-class'] = 'odds-wrap ';
            } else {
                d[prefix + 'odds-id'] = 0;
                d[prefix + 'cell-class'] = disabledClass ? disabledClass : '';
                d[prefix + 'cursor-class'] = '';
                d[prefix + 'text'] = '&#xA0;';
                d['price-x-' + i + '-text'] = '&#xA0;';
                d['odds-' + marketName + '-' + optionNames[i] + '-cell-class'] = '';
            }
        }
    };
    this.clearOdds = function (d, marketDisplayId, isFrozen) {
        var marketName = _marketDisplayTemplateNames[marketDisplayId];
        if (!marketName) return;
        var optionNames = _marketDisplayOptionTemplateNames[marketName];
        var c = optionNames.length;
        for (var i = 0; i < c; ++i) {
            var prefix = 'price-' + marketName + '-' + optionNames[i] + '-';
            d[prefix + 'cell-class'] = isFrozen ? 'frozen-odds' : '';
            d[prefix + 'text'] = '&#xA0;';
            d['odds-' + marketName + '-' + optionNames[i] + '-cell-class'] = '';
            d[prefix + 'cursor-class'] = '';
            d[prefix + 'odds-id'] = 0;
            d[prefix + 'odds-option'] = '';
            d[prefix + 'price-value'] = '';
        }
    };
    this.populateOddsHDPStyle = function (d, odd) {
        if (odd) {
            var hdp = odd[1][4];
            d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
            d['home-color-class'] = hdp > 0 ? 'Red' : 'Blue';
            d['away-color-class'] = hdp < 0 ? 'Red' : 'Blue';
        }
    };
    this.clearOddsHDPStyle = function (d, className) {
        var hdpClass = className ? className : '';
        d['hdp-type'] = hdpClass;
        d['home-color-class'] = hdpClass;
        d['away-color-class'] = hdpClass;
    };
    this.changeRowsColor = function (id, color, count) {
        for (var i = 0; i < count; i++) {
            var row = document.getElementById(id + '-' + i);
            if (row) {
                row.bgColor = color;
            }
        }
        var event = window.event;
        if (event) {
            if (event.stopPropagation) {
                event.stopPropagation();
            } else {
                event.cancelBubble = true;
            }
        }
    };
    this.addClassName = function (element, className) {
        if (element) {
            element.className = TiLib.Text.addClassItem(element.className, className);
        }
    };
    this.removeClassName = function (element, className) {
        if (element) {
            element.className = TiLib.Text.removeClassItem(element.className, className);
        }
    };
    this.changeLIColor = function (event, color) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            if (e.nodeName == 'LI') {
                e.style.backgroundColor = color;
                break;
            }
            e = e.parentNode;
        }
    }
    this.openStatistics = function (eventId) {
        TiLib.Window.openWindow('/web-root/restricted/odds-display/statistics.aspx?id=' + eventId, 'Statistics', 'scrollbars=no,resizable=no,width=1000,height=600');
    };
    this.openTV = function (sportId, isToday) {
        TiLib.Window.openWindow('tv.aspx?sport=' + sportId + '&today=' + (isToday ? '1' : '0'), 'tv', 'toolbar=0,scrollbars=yes,location=0,statusbar=0,menubar=0,resizable=0,width=640,height=600,left=660,top=200');
    };
    this.openDoublePromoTnC = function (link) {
        TiLib.Window.openWindow(link, 'DoublePromotion', 'toolbar=0,scrollbars=yes,location=0,statusbar=0,menubar=0,resizable=0,width=1024,height=600,left=660,top=200');
    }
    this.openLiveCenter = function (eventId) {
        var w = window.top.document.getElementById("leftFrame").contentWindow;
        if (w && w.openLiveCenter) {
            w.openLiveCenter(eventId);
        }
    };
    this.openForecast = function (eventResultId, elementId) {
        var w = window.top.document.getElementById("leftFrame").contentWindow;
        if (w && w.$Forecast) {
            w.$Forecast.open(eventResultId, elementId);
        }
    };
    this.closeForecast = function () {
        var w = window.top.document.getElementById("leftFrame").contentWindow;
        if (w && w.$Forecast) {
            w.$Forecast.onClose();
        }
    };
    this.openVideo = function (eventId) {
        var names = window.top.document.getElementById("topFrame").contentWindow.od_Live_Video_Name;
        var refs = window.top.document.getElementById("topFrame").contentWindow.od_Live_Video_Ref;
        var counts = window.top.document.getElementById("topFrame").contentWindow.od_Live_Video_Count;
        var index = 0;
        counts[0]++;
        for (var i = 0; i < 5; ++i) {
            if (!(refs[i] && refs[i].open && !refs[i].closed)) {
                index = i;
                break;
            }
        }
        if (i == 5) {
            index = counts[0] % 5;
        }
        var param;
        if (TiLib.Browser.isFirefox()) {
            param = 'scrollbars=no,resizable=no,width=785,height=373';
        } else if (TiLib.Browser.isInternetExplorer()) {
            param = (TiLib.Browser.getVersion() <= 6) ? 'scrollbars=no,resizable=no,width=783,height=373' : 'scrollbars=no,resizable=no,width=784,height=372';
        } else if (TiLib.Browser.isChrome()) {
            param = 'scrollbars=no,resizable=no,width=786,height=377';
        } else if (TiLib.Browser.isSafari()) {
            param = 'scrollbars=no,resizable=no,width=785,height=375';
        } else {
            param = 'scrollbars=no,resizable=no,width=783,height=373';
        }
        refs[index] = TiLib.Window.openWindow('/web-root/restricted/video/video-page.aspx?event=' + eventId, names[index], param);
    };
    this.updateFavouriteSports = function (sports) {
        var w = window.top.document.getElementById("leftFrame").contentWindow;
        if (w) {
            w.drawFavSports(sports);
        }
    };
    this.onMouseOverRefreshDiv = function () {
        var refreshImg = document.getElementById('RefreshImg');
        if (refreshImg && refreshImg.className == 'RefreshUp') {
            refreshImg.className = 'RefreshOver';
        }
    };
    this.onMouseOutRefreshDiv = function () {
        var refreshImg = document.getElementById('RefreshImg');
        if (refreshImg && refreshImg.className == 'RefreshOver') {
            refreshImg.className = 'RefreshUp';
        }
    };
    this.onReposition = function () {
        var windowHeight = document.documentElement.clientHeight;
        var windowWidth = document.documentElement.clientWidth;
        var alertDiv = document.getElementById("divContainer");
        if (alertDiv && windowHeight > 350) {
            var windowLeft = windowWidth > (785 + 250) ? 785 : 535;
            alertDiv.style.position = 'absolute';
            alertDiv.style.left = windowLeft + 'px';
            if (document.body.scrollLeft || document.body.scrollTop) {
                alertDiv.style.top = document.body.scrollTop + (windowHeight - alertDiv.offsetHeight) + 'px';
            } else {
                alertDiv.style.top = document.documentElement.scrollTop + (windowHeight - alertDiv.offsetHeight) + 'px';
            }
        }
        var refreshDiv = document.getElementById('RefreshDiv');
        if (refreshDiv) {
            if (screen.width > 1024) {
                refreshDiv.style.display = 'block';
                refreshDiv.style.position = 'absolute';
                refreshDiv.style.left = 785 + 'px';
                if (document.body.scrollLeft || document.body.scrollTop) {
                    refreshDiv.style.top = document.body.scrollTop + 'px';
                } else {
                    refreshDiv.style.top = document.documentElement.scrollTop + 'px';
                }
            } else {
                refreshDiv.style.display = "none";
            }
        };
    }
}
var OddsUtility = new __OddsUtility();

function __Cache_InterestedEvent() {
    var _eventOrders = {};
    var _eventDictionary = {};
    var _eventResultDictionary = {};
    var _eventResultExtraDictionary = {};
    var _oddsDictionary = {};
    var _marketGroupDictionary = {};
    var _tagEventResultDictionary = {};
    var _tagEventResultArray = [];
    var _tagEventResultArrayByEventId = {};
    var _orderedEventArray = [];
    var _oddsIdArrayByEventId = {};
    var _priceAdjustIndicators = null;
    var _scoreAdjustIndicators = null;
    var _liveStartTimes = null;
    var _self = this;
    this.update = function (clearAll, data, priceStyle) {
        var isChanged = false;
        _priceAdjustIndicators = null;
        _scoreAdjustIndicators = null;
        if (clearAll) {
            isChanged = true;
            _eventDictionary = {};
            _eventResultDictionary = {};
            _oddsDictionary = {};
            _marketGroupDictionary = {};
        }
        if (data) {
            if (data[1]) {
                isChanged = true;
                _clearInvalidOdds(data[1]);
                _updateElements(_eventDictionary, data[1]);
            }
            if (data[2]) {
                isChanged = true;
                _updateEventResults(_eventResultDictionary, data[2]);
            }
            if (data[3]) {
                isChanged = true;
                _updateEventResultExtras(_eventResultExtraDictionary, data[3]);
            }
            if (data[4]) {
                isChanged = true;
                _updateOdds(_oddsDictionary, data[4], priceStyle);
            }
            if (data[5]) {
                isChanged = true;
                _deleteElements(_oddsDictionary, data[5]);
            }
            if (data[6]) {
                isChanged = true;
                _updateElements(_marketGroupDictionary, data[6]);
            }
            _eventOrders = {};
            var eventIdArray = data[0];
            _orderedEventArray = [];
            for (var i = 0; i < eventIdArray.length; ++i) {
                _eventOrders[eventIdArray[i]] = i;
                if (_eventDictionary[eventIdArray[i]]) {
                    _orderedEventArray.push(_eventDictionary[eventIdArray[i]]);
                }
            }
        }
        _normalize();
        return isChanged;
    };
    this.getTagEventResultArray = function () {
        return _tagEventResultArray;
    };
    this.getTagEventResultArrayByEventId = function (eventId) {
        return _tagEventResultArrayByEventId[eventId];
    };
    this.hasFrozenOddsCount = function (eventResultId) {
        return (_eventResultExtraDictionary && _eventResultExtraDictionary[eventResultId] && _eventResultExtraDictionary[eventResultId][1]);
    };
    this.getFrozenOddsCount = function (eventResultId, marketId) {
        if (!_eventResultExtraDictionary || !_eventResultExtraDictionary[eventResultId] || !_eventResultExtraDictionary[eventResultId][1] || !_eventResultExtraDictionary[eventResultId][1][marketId]) {
            return 0;
        }
        return _eventResultExtraDictionary[eventResultId][1][marketId];
    };
    this.getRedCards = function (eventResultId) {
        if (!_eventResultExtraDictionary || !_eventResultExtraDictionary[eventResultId]) {
            return null;
        } else {
            return {
                'home': _eventResultExtraDictionary[eventResultId][5],
                'away': _eventResultExtraDictionary[eventResultId][6]
            };
        }
    };
    this.getEventResultExtra = function (eventResultId) {
        if (!_eventResultExtraDictionary || !_eventResultExtraDictionary[eventResultId]) {
            return null;
        } else {
            return _eventResultExtraDictionary[eventResultId];
        }
    };
    this.getOrderedEventArray = function () {
        return _orderedEventArray;
    };
    this.isEmpty = function () {
        return _tagEventResultArray.length > 0 ? false : true;
    };
    this.getPriceAdjustIndicators = function (oddsId) {
        return (_priceAdjustIndicators && _priceAdjustIndicators[oddsId]) ? _priceAdjustIndicators[oddsId] : [];
    };
    this.getLiveStartTime = function (eventResultId) {
        return _liveStartTimes ? _liveStartTimes[eventResultId] : null;
    };
    this.clearAdjustIndicators = function () {
        if (_priceAdjustIndicators || _scoreAdjustIndicators) {
            _priceAdjustIndicators = null;
            _scoreAdjustIndicators = null;
            return true;
        } else {
            return false;
        }
    };
    this.getShowingEventsParam = function () {
        if (!_eventDictionary) {
            return '';
        }
        var ret = '';
        for (var key in _eventDictionary) {
            if (ret != '') ret += ',';
            ret += key + ',';
            ret += _eventDictionary[key][8];
        }
        return ret;
    };
    this.hasEventId = function (eventId) {
        if (!_eventDictionary) {
            return false;
        }
        for (var key in _eventDictionary) {
            if (key == eventId)
                return true;
        }
        return false;
    };

    function _updateElements(elementDictionary, elementArray) {
        if (!elementArray) return;
        var c = elementArray.length;
        for (var i = 0; i < c; ++i) {
            var element = elementArray[i];
            if (!element) continue;
            var elementId = element[0];
            var oldElement = elementDictionary[elementId];
            if (oldElement) {
                element = oldElement.updateArray(element);
            }
            elementDictionary[elementId] = element;
        }
    }

    function _deleteElements(elementDictionary, elementIdArray) {
        if (!elementIdArray) return;
        var c = elementIdArray.length;
        for (var i = 0; i < c; ++i) {
            var elementId = elementIdArray[i];
            if (!elementId) continue;
            delete elementDictionary[elementId];
        }
    }

    function _clearInvalidOdds(eventArray) {
        for (var i = 0; i < eventArray.length; i++) {
            var newEvent = eventArray[i];
            var eventId = newEvent[0];
            var currentEvent = _orderedEventArray[_eventOrders[eventId]];
            if (currentEvent && newEvent[8] != currentEvent[8]) {
                var tagEventResults = _tagEventResultArrayByEventId[eventId];
                for (var j = 0; j < tagEventResults.length; j++) {
                    if (!_eventResultDictionary[tagEventResults[j][0]]) continue;
                    var eventResultId = tagEventResults[j][0];
                    delete _eventResultDictionary[eventResultId];
                    _deleteOddsByEventResultId(eventResultId);
                }
            }
        }
    }

    function _deleteOddsByEventResultId(eventResultId) {
        if (eventResultId && _oddsDictionary) {
            for (var oddId in _oddsDictionary) {
                var odds = _oddsDictionary[oddId];
                if (odds && odds.length > 2) {
                    var oddEventResultId = odds[1][0];
                    if (oddEventResultId == eventResultId) {
                        delete _oddsDictionary[oddId];
                    }
                }
            }
        }
    }

    function _updateEventResults(eventResultDictionary, eventResultArray) {
        if (!eventResultArray) return;
        var c = eventResultArray.length;
        for (var i = 0; i < c; ++i) {
            var eventResult = eventResultArray[i];
            if (!eventResult) continue;
            var eventResultId = eventResult[0];
            var oldEventResult = eventResultDictionary[eventResultId];
            if (oldEventResult) {
                eventResult = oldEventResult.updateArray(eventResult);
                if (eventResult[3] != oldEventResult[3] || eventResult[4] != oldEventResult[4]) {
                    if (!_scoreAdjustIndicators) {
                        _scoreAdjustIndicators = {};
                    }
                    _scoreAdjustIndicators[eventResultId] = true;
                }
            }
            eventResultDictionary[eventResultId] = eventResult;
        }
    }

    function _updateEventResultExtras(eventResultExtraDictionary, eventResultExtraArray) {
        if (!eventResultExtraArray) return;
        var c = eventResultExtraArray.length;
        for (var i = 0; i < c; ++i) {
            var eventResultExtra = eventResultExtraArray[i];
            if (!eventResultExtra) continue;
            var eventResultId = eventResultExtra[0];
            var oldEventResultExtra = eventResultExtraDictionary[eventResultId];
            if (oldEventResultExtra) {
                eventResultExtra = oldEventResultExtra.updateArray(eventResultExtra);
            }
            if (!_liveStartTimes) {
                _liveStartTimes = {};
            }
            _liveStartTimes[eventResultId] = new Date();
            eventResultExtraDictionary[eventResultId] = eventResultExtra;
        }
    }

    function _updateOdds(oddsDictionary, oddsArray, priceStyle) {
        if (!oddsArray) return;
        var c = oddsArray.length;
        for (var i = 0; i < c; ++i) {
            var odds = oddsArray[i];
            if (!odds) continue;
            var oddsId = odds[0];
            var oldOdds = oddsDictionary[oddsId];
            if (oldOdds) {
                odds = oldOdds.updateArray(odds);
                var oldPrices = oldOdds[2];
                var newPrices = odds[2];
                var priceCount = newPrices.length;
                for (var priceIndex = 0; priceIndex < priceCount; ++priceIndex) {
                    var indicator = 0;
                    var oldPrice = oldPrices[priceIndex];
                    var newPrice = newPrices[priceIndex];
                    if (oldPrice == newPrice) continue;
                    if (priceStyle == 3) {
                        indicator = (newPrice > oldPrice) ? 1 : -1;
                    } else {
                        if (oldPrice > 0) {
                            if (newPrice > 0) {
                                indicator = (newPrice > oldPrice) ? 1 : -1;
                            } else {
                                indicator = 1;
                            }
                        } else {
                            if (newPrice > 0) {
                                indicator = -1;
                            } else {
                                indicator = (newPrice > oldPrice) ? 1 : -1;
                            }
                        }
                    }
                    if (indicator != 0) {
                        if (!_priceAdjustIndicators) {
                            _priceAdjustIndicators = {};
                        }
                        var indicators = _priceAdjustIndicators[oddsId];
                        if (!indicators) {
                            indicators = [];
                            _priceAdjustIndicators[oddsId] = indicators;
                        }
                        indicators[priceIndex] = indicator;
                    }
                }
            }
            oddsDictionary[oddsId] = odds;
        }
    }

    function _normalize() {
        var oddsByEventResultId = {};
        for (var oddsId in _oddsDictionary) {
            var odds = _oddsDictionary[oddsId];
            var eventResultId = odds[1][0];
            var eventResult = _eventResultDictionary[eventResultId];
            if (!eventResult) {
                delete _oddsDictionary[oddsId];
                continue;
            }
            var oddsByMarketDisplayId = oddsByEventResultId[eventResultId];
            if (!oddsByMarketDisplayId) {
                oddsByMarketDisplayId = {};
                oddsByEventResultId[eventResultId] = oddsByMarketDisplayId;
            }
            var marketDisplayId = odds[1][1];
            var oddsArray = oddsByMarketDisplayId[marketDisplayId];
            if (!oddsArray) {
                oddsArray = [];
                oddsByMarketDisplayId[marketDisplayId] = oddsArray;
            }
            oddsArray.push(odds);
        }
        for (eventResultId in oddsByEventResultId) {
            oddsByMarketDisplayId = oddsByEventResultId[eventResultId];
            for (marketDisplayId in oddsByMarketDisplayId) {
                oddsArray = oddsByMarketDisplayId[marketDisplayId];
                oddsArray.sort(_sortOddsCallback);
            }
        }
        var normalizedMarketGroupDiciionary = {};
        for (var marketGroupId in _marketGroupDictionary) {
            var marketGroup = _marketGroupDictionary[marketGroupId];
            var normalizedMarketGroup = marketGroup.updateArray(marketGroup, []);
            normalizedMarketGroup[2] = TiLib.Template.createTemplate(normalizedMarketGroup[2]);
            normalizedMarketGroup[3] = TiLib.Template.createTemplate(normalizedMarketGroup[3]);
            normalizedMarketGroupDiciionary[marketGroupId] = normalizedMarketGroup;
        }
        _tagEventResultDictionary = {};
        _tagEventResultArrayByEventId = {};
        _tagEventResultArray = [];
        var eventId = 0;
        var deletedEventResultIds = [];
        for (eventResultId in _eventResultDictionary) {
            eventResult = _eventResultDictionary[eventResultId];
            if (!eventResult) continue;
            oddsByMarketDisplayId = oddsByEventResultId[eventResultId];
            if (!oddsByMarketDisplayId && !_self.hasFrozenOddsCount(eventResultId)) continue;
            eventId = eventResult[1];
            var event = _eventDictionary[eventId];
            marketGroupId = eventResult[2];
            marketGroup = normalizedMarketGroupDiciionary[marketGroupId];
            var tagEventResult = [eventResultId, event, eventResult, oddsByMarketDisplayId, marketGroup];
            _tagEventResultDictionary[eventResultId] = tagEventResult;
            if (!_tagEventResultArrayByEventId[eventId]) {
                _tagEventResultArrayByEventId[eventId] = [];
            }
            _tagEventResultArrayByEventId[eventId].push(tagEventResult);
            _tagEventResultArray.push(tagEventResult);
        }
        _tagEventResultArray.sort(_sortTagEventResultCallback);
        for (var eId in _tagEventResultArrayByEventId) {
            _tagEventResultArrayByEventId[eId].sort(_sortTagEventResultCallback);
        }
    }

    function _sortTagEventResultCallback(tagEventResult1, tagEventResult2) {
        var eventId1 = tagEventResult1[1][0];
        var eventId2 = tagEventResult2[1][0];
        var eventResult1 = tagEventResult1[2];
        var eventResult2 = tagEventResult2[2];
        var marketGroup1 = tagEventResult1[4];
        var marketGroup2 = tagEventResult2[4];
        if (eventId1 != eventId2) {
            return _eventOrders[eventId1] - _eventOrders[eventId2];
        } else if (marketGroup1 && marketGroup2) {
            if (marketGroup1[4] != marketGroup2[4]) {
                return marketGroup1[4] - marketGroup2[4];
            }
        } else if (marketGroup1) {
            return 1;
        } else if (marketGroup2) {
            return -1;
        }
        return eventResult1[0] - eventResult2[0];
    }

    function _sortOddsCallback(odds1, odds2) {
        var maxbet1 = odds1[1][3];
        var maxbet2 = odds2[1][3];
        if (maxbet1 != maxbet2) {
            return (maxbet1 > maxbet2) ? -1 : 1;
        }
        return (odds1[0] < odds2[0]) ? -1 : 1;
    }
}

function __Module_InterestedEvent(refreshRate) {
    var _MarketDisplay = {
        FTimeHDP: 1,
        FTimeOE: 2,
        FTimeOU: 3,
        FTimeCS: 4,
        FTime1X2: 5,
        TG: 6,
        FHalfHDP: 7,
        FHalf1X2: 8,
        FHalfOU: 9,
        HTFT: 10,
        ML: 11,
        FHalfOE: 12,
        FGLG: 13,
        FHalfCS: 14,
        DC: 15,
        FTimeLS: 16,
        FHalfLS: 17
    };
    var _TemplateName = 'odds-display/interested-event';
    var _self = this;
    var _template = null;
    var _cache = new __Cache_InterestedEvent();
    var _expandedEventId = -1;
    var _expandingEventId = 0;
    var _containerHeight = 0;
    var _maxEventBodyHeight = 0;
    var _ignoreRefreshWay = false;
    var _selectedOddId = null;
    var _syn = {
        waitingTemplate: false,
        drawing: false,
        refreshRate: refreshRate,
        refreshCount: 0,
        cooldownCount: 0,
        failureCount: 0,
        version: 0
    };
    var _closedMarketsByEventResultId = [];
    this.onOrderSubmitted = function () {
        _syn.version = 0;
        _expandedEventId = -1;
        _expandingEventId = 0;
        _resetExpandedEventId();
        _submit();
    };
    this.toggleExpandEvent = function (eventId) {
        if (_cache.hasEventId(eventId)) {
            var eventBodyId;
            var eventBody;
            var isClosing;
            _expandingEventId = eventId;
            if (_expandingEventId == _expandedEventId) {
                isClosing = _expandedEventId > 0 && _cache.hasEventId(_expandedEventId);
                if (isClosing) {
                    eventBodyId = 'event-body-' + _expandedEventId;
                    _resetExpandedEventId(_expandedEventId);
                    _expandedEventId = 0;
                    _expandingEventId = 0;
                    eventBody = document.getElementById(eventBodyId);
                    if (eventBody) {
                        eventBody.style.display = "block";
                        _disableScrollBar(eventBodyId);
                    }
                    if ($M('global').isQuirkMode()) {
                        if (eventBody) {
                            eventBody.style.display = "none";
                        }
                    } else {
                        TiLib.UI.addCollapseEffect(eventBodyId, 200, _toggleEventComplete);
                    }
                } else {
                    _expandedEventId = 0;
                    _expandingEventId = 0;
                }
            } else {
                isClosing = _expandedEventId > 0 && _cache.hasEventId(_expandedEventId);
                if (isClosing) {
                    eventBodyId = 'event-body-' + _expandedEventId;
                    eventBody = document.getElementById(eventBodyId);
                    if (eventBody) {
                        eventBody.style.display = "block";
                        _disableScrollBar(eventBodyId);
                    }
                    TiLib.UI.addCollapseEffect(eventBodyId, 200);
                }
                eventBodyId = 'event-body-' + _expandingEventId;
                _expandedEventId = _expandingEventId;
                _expandingEventId = 0;
                TiLib.UI.addExpandEffect(eventBodyId, 200, _toggleEventComplete);
                _setExpandedEventId(_expandedEventId);
            }
        }
    };

    function _toggleMarketClosed(eventResultId, marketId) {
        var marketBodyId = 'market-body-' + eventResultId + '-' + marketId;
        var marketBody;
        if (!_closedMarketsByEventResultId) {
            _closedMarketsByEventResultId = [];
        }
        if (!_closedMarketsByEventResultId[eventResultId]) {
            _closedMarketsByEventResultId[eventResultId] = [];
        }
        if (!_isMarketIsClosedInCookie(eventResultId, marketId) && (!_closedMarketsByEventResultId[eventResultId][marketId])) {
            marketBody = document.getElementById(marketBodyId);
            marketBody.style.display = "none";
            _applyScrollBar();
            TiLib.UI.addCollapseEffect(marketBodyId, 200);
            _closedMarketsByEventResultId[eventResultId][marketId] = 1;
            _setResetClosedEventMarket(eventResultId, marketId, true);
        } else {
            marketBody = document.getElementById(marketBodyId);
            marketBody.style.display = "block";
            _applyScrollBar();
            TiLib.UI.addExpandEffect(marketBodyId, 200);
            delete _closedMarketsByEventResultId[eventResultId][marketId];
            _setResetClosedEventMarket(eventResultId, marketId, false);
        }
    }

    function _isMarketClosed(eventResultId, marketId) {
        if (_isMarketIsClosedInCookie(eventResultId, marketId)) {
            return true;
        }
        if (!_closedMarketsByEventResultId || !_closedMarketsByEventResultId[eventResultId] || !_closedMarketsByEventResultId[eventResultId][marketId]) {
            return false;
        }
        return _closedMarketsByEventResultId[eventResultId][marketId] == 1;
    }

    function _setExpandedEventId(expandedEventId) {
        var eventBodyId = 'interested-event-body-expanded';
        var ev = CookieHelper.getValue(eventBodyId);
        if (!ev && ev != '') {
            ev = '';
        } else {
            ev = ev.split('@1').join('@0');
        }
        if (ev.indexOf('~' + expandedEventId) == -1) {
            ev = ev + '~' + expandedEventId + '@1';
        } else {
            if (ev.indexOf('~' + expandedEventId + '@0') > -1) {
                ev = ev.replace('~' + expandedEventId + '@0', '~' + expandedEventId + '@1');
            }
        }
        CookieHelper.setValue(eventBodyId, ev, 86400000);
    }

    function _resetExpandedEventId(eventId) {
        var eventBodyId = 'interested-event-body-expanded';
        var value = '';
        if (eventId) {
            value = CookieHelper.getValue(eventBodyId);
            if (value) {
                if (value.indexOf('~' + eventId) > -1) {
                    if (value.indexOf('~' + eventId + '@1') > -1) {
                        value = value.replace('~' + eventId + '@1', '~' + eventId + '@0');
                    }
                } else {
                    value = value + '~' + eventId + '@0';
                }
            } else {
                value = '~' + eventId + '@0';
            }
        }
        CookieHelper.setValue(eventBodyId, value, 86400000);
    }

    function _checkExpandedEventIdIsCollapsed(eventId) {
        var eventBodyId = 'interested-event-body-expanded';
        if (eventId) {
            value = CookieHelper.getValue(eventBodyId);
            if (value) {
                if (value.indexOf('~' + eventId + '@0') > -1) {
                    return true;
                }
            }
        }
        return false;
    }

    function _getExpandedEventId() {
        var eventBodyId = 'interested-event-body-expanded';
        var expandedEidStr = CookieHelper.getValue(eventBodyId);
        if (expandedEidStr && expandedEidStr != '') {
            var eid = expandedEidStr.split('~');
            for (var i = 0; i < eid.length; i++) {
                var e = eid[i];
                var expanded = e.split('@');
                if (expanded.length == 2 && parseInt(expanded[1], 10) == 1) {
                    return expanded[0];
                }
            }
        }
        return -1;
    }

    function _setResetClosedEventMarket(eventResultId, marketId, setFlag) {
        var evMkCookieId = 'interested-event-market-expanded';
        var evmkt = CookieHelper.getValue(evMkCookieId);
        if (!evmkt && evmkt != '') {
            evmkt = '';
        }
        var marketBodyId = eventResultId + '-' + marketId;
        if (setFlag) {
            if (evmkt.indexOf('~' + marketBodyId) == -1) {
                evmkt = evmkt + '~' + marketBodyId;
            }
        } else {
            if (evmkt.indexOf('~' + marketBodyId) > -1) {
                evmkt = evmkt.replace('~' + marketBodyId, '');
            }
        }
        CookieHelper.setValue(evMkCookieId, evmkt, 86400000);
    }

    function _isMarketIsClosedInCookie(eventResultId, marketId) {
        var evMkCookieId = 'interested-event-market-expanded';
        var evmkt = CookieHelper.getValue(evMkCookieId);
        if (!evmkt) {
            return false;
        }
        var marketBodyId = eventResultId + '-' + marketId;
        var list = evmkt.split('~');
        var exist = false;
        for (var i = 0; i < list.length; i++) {
            if (list[i] == marketBodyId) {
                exist = true;
                break;
            }
        }
        return exist;
    }

    function _toggleEventComplete() {
        _applyScrollBar();
    }

    function _onWindowResize(event) {
        _containerHeight = event.height - 25;
        _draw();
    }

    function _calculateMaxBodyHeight() {
        _maxEventBodyHeight = _containerHeight - 10;
        if (_maxEventBodyHeight <= 0) return;
        var refreshDiv = document.getElementById('r-refresh-button-container');
        if (refreshDiv) {
            _maxEventBodyHeight -= refreshDiv.offsetHeight;
        }
        var miniGameDiv = document.getElementById('right-column-mini-game-tab');
        if (miniGameDiv) {
            _maxEventBodyHeight -= miniGameDiv.offsetHeight;
        }
        var eventArray = _cache.getOrderedEventArray();
        if (eventArray) {
            for (var i = 0; i < eventArray.length; i++) {
                var eventTitleDiv = document.getElementById('bu:ie:ev:' + eventArray[i][0]);
                if (eventTitleDiv) {
                    _maxEventBodyHeight -= eventTitleDiv.offsetHeight;
                }
            }
            for (var i = 0; i < eventArray.length; i++) {
                var eventId = eventArray[i][0];
                var eventBody = document.getElementById("event-body-" + eventId);
                if (eventBody) {
                    if (eventId != _expandedEventId) {
                        eventBody.style.display = "none";
                        var fullbd = document.getElementById('event-fbody-' + eventId);
                        if (fullbd) {
                            fullbd.className = 'event-view-repeat';
                        }
                    }
                }
            }
        }
    }
    var _scrollTop = {};

    function _applyScrollBar() {
        var lastPosition = _scrollTop[_expandedEventId];
        var offset = 0;
        if ($M('global').isQuirkMode()) {
            offset = -15;
        }
        ScrollDiv.draw('event-body-' + _expandedEventId, _maxEventBodyHeight + offset, null, lastPosition);
    }

    function _disableScrollBar(elementId) {
        ScrollDiv.hideRail(elementId);
        setTimeout(function () {
            ScrollDiv.showRail(elementId);
        }, 1000);
    }

    function _getDisplaySetting(key) {
        if ($M('odds-display') && $M('odds-display').getDisplaySetting) {
            return $M('odds-display').getDisplaySetting(key);
        } else if ($M('live-sport-display') && $M('live-sport-display').getDisplaySetting) {
            return $M('live-sport-display').getDisplaySetting(key);
        } else {
            return null;
        }
    }

    function _setDisplaySetting(key, value) {
        if ($M('odds-display') && $M('odds-display').setDisplaySetting) {
            return $M('odds-display').setDisplaySetting(key, value);
        } else if ($M('live-sport-display') && $M('live-sport-display').setDisplaySetting) {
            return $M('live-sport-display').setDisplaySetting(key, value);
        } else {
            return null;
        }
    }
    this.initiate = function () {
        TiLib.Timer.addToSecondTimer(_self);
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        TiLib.Event.addListener('viewportsize', _onWindowResize);
    };
    this.onTime = function () {
        if (_syn.cooldownCount) {
            _syn.cooldownCount--;
        } else {
            if (_syn.drawing) {
                if (_syn.failureCount > 3) {
                    _syn.drawing = false;
                } else {
                    _syn.failureCount++;
                }
            } else if (_syn.refreshCount > 0) {
                _drawRefreshButtons();
                _syn.refreshCount--;
            } else {
                _syn.refreshCount = _syn.refreshRate;
                _syn.cooldownCount = 2;
                _syn.drawing = true;
                _syn.failureCount = 0;
                _submit();
                _drawRefreshButtons();
            }
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:ie:r-refresh:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons();
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:ie:r-refresh:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons();
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_syn.waitingTemplate) {
                    if (_template) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                }
            }
        }
    };
    this.onIdle = function (version) {
        if (_syn.version < version) {
            _syn.version = version;
        }
        if (_cache.clearAdjustIndicators()) {
            _draw();
        }
        _syn.drawing = false;
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var clearAll = data[1];
        var cacheData = data[2];
        _cache.clearAdjustIndicators();
        if (version != _syn.version) {
            _ignoreRefreshWay = true;
        }
        _syn.version = version;
        _cache.update(clearAll, cacheData, _getDisplaySetting('price-style'));
        var eventArray = _cache.getOrderedEventArray();
        $M('right-column').hasInterestedEvent(eventArray && eventArray.length > 0);
        if (_expandedEventId != 0 && !_cache.hasEventId(_expandedEventId)) {
            _expandedEventId = -1;
            var currExpandedIDinCookie = _getExpandedEventId();
            if (currExpandedIDinCookie && currExpandedIDinCookie > -1) {
                _expandingEventId = currExpandedIDinCookie;
            } else {
                var events = _cache.getOrderedEventArray();
                if (events && events.length > 0) {
                    if (events[events.length - 1]) {
                        var eid = events[events.length - 1][0];
                        if (!_checkExpandedEventIdIsCollapsed(eid)) {
                            _expandingEventId = eid;
                        }
                    }
                }
            }
        }
        _draw();
        _syn.drawing = false;
    };

    function _submit() {
        var sb = [];
        sb.push('/web-root/restricted/odds-display/interested-event-data.aspx?price-style=');
        sb.push(_getDisplaySetting('price-style'));
        sb.push('&es=');
        sb.push(_cache.getShowingEventsParam());
        sb.push('&v=');
        sb.push(_syn.version);
        return TiLib.Ajax.sendRequest('interested-event', sb.join(''));
    }
    this.onClick = function (event) {
        if (!event) event = window.event;
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    };

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            var element = e;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'ie') {
                switch (atom[2]) {
                case 'price':
                    if (count >= 6) {
                        _openTicket(atom[3], atom[4], atom[5], atom[6], element, id);
                    }
                    return false;
                case 'ev':
                    if (count >= 4) {
                        var eventId = parseInt(atom[3]);
                        _resetEventBodyToExpanded();
                        _self.toggleExpandEvent(eventId);
                        _setEventBodyToExpanded();
                    }
                    return false;
                case 'r-refresh':
                    _self.refresh();
                    return false;
                case 'market-title':
                    if (count >= 5) {
                        _toggleMarketClosed(atom[3], atom[4]);
                        _ignoreRefreshWay = true;
                        _draw();
                        _ignoreRefreshWay = false;
                    }
                    return false;
                }
            }
        }
        return true;
    }
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.version = 0;
        } else {
            if (_syn.cooldownCount) {
                return;
            } else if (_syn.drawing) {
                if (_syn.failureCount > 3) {
                    _syn.drawing = false;
                } else {
                    _syn.failureCount++;
                }
                return;
            }
        }
        _syn.refreshCount = _syn.refreshRate;
        _syn.cooldownCount = 2;
        _syn.drawing = true;
        _syn.failureCount = 0;
        _submit();
    };
    var _selectedElements = {};
    var _refNodes = {};
    var _firstOpen = false;

    function _openTicket(oddsId, option, price, hdpType, element, id) {
        var betPage = $M('ticket').getBetPageEnum('interestedEvent');
        $M('ticket').openTicket(oddsId, option, price, hdpType, false, false, betPage);
        while (element) {
            var className = element.className;
            if (className && className.indexOf('dummy-class') >= 0) {
                _refNodes[oddsId + option] = element;
                break;
            }
            element = element.parentNode;
        }
    }
    this.clearSelectedOdds = function () {
        var force = true;
        var oddIdOption = $M('ticket').getOddIdOption(force);
        if (oddIdOption) {
            for (var selectedOddIdOption in _selectedElements) {
                var node = _refNodes[selectedOddIdOption];
                if (node) {
                    var className = node.className;
                    node.className = className.replace('odds-selected', 'dummy-class');
                }
            }
            _selectedElements = {};
            var node = _refNodes[oddIdOption];
            if (node) {
                var className = node.className;
                className = className.replace('odds-change', '');
                node.className = className.replace('dummy-class', 'odds-selected');
                _selectedElements[oddIdOption] = 1;
            } else {}
        }
    }
    this.draw = function () {
        _draw();
    };

    function _draw() {
        var div = document.getElementById('event-body-' + _expandedEventId);
        if (div) {
            _scrollTop[_expandedEventId] = div.scrollTop;
        }
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var usesLocalTime = _getDisplaySetting('display-in-local-time');
        var eventArray = _cache.getOrderedEventArray();
        var event;
        var content = '';
        var eventHTMLs = [];
        var eventHTML;
        var eventCount;
        var d = {};
        var tagEventResults;
        var tagEventResult;
        var isRefreshProcessing = true;
        if (eventArray && eventArray.length > 0) {
            for (eventCount = 0; eventCount < eventArray.length; eventCount++) {
                var isLive;
                d = {};
                event = eventArray[eventCount];
                d['event-id'] = event[0];
                d['home'] = TiLib.Text.encodeHTML(event[3]);
                d['away'] = TiLib.Text.encodeHTML(event[4]);
                d['home-style'] = 'blue';
                d['away-style'] = 'blue';
                switch (event[7]) {
                case 1:
                    d['home-style'] = 'red';
                    break;
                case 2:
                    d['away-style'] = 'red';
                    break;
                default:
                    break;
                }
                if (event[8] == 0) {
                    eventHTML = _template['event-live'];
                } else {
                    eventHTML = _template['event-nonlive'];
                }
                var showSpecialRow = true;
                var blocks = [];
                tagEventResults = _cache.getTagEventResultArrayByEventId(event[0]);
                var flag = 0;
                var tagEventResultCount;
                for (tagEventResultCount = 0; tagEventResultCount < tagEventResults.length; tagEventResultCount++) {
                    tagEventResult = tagEventResults[tagEventResultCount];
                    var mainEventResult = tagEventResult[2];
                    if (event[8] == 0 && !flag) {
                        if (mainEventResult) {
                            d['home-score'] = mainEventResult[3];
                            d['away-score'] = mainEventResult[4];
                            d['live-score'] = _template['live-score'].getText(d);
                            flag = 1;
                        }
                        d['live-time'] = _template['time-live'].getText(d);
                    }
                    var marketGroup = tagEventResult[4];
                    if (!marketGroup || marketGroup[0] == 0) {
                        var isLive = event[8] == 0;
                        _populateMainMarkets(blocks, tagEventResult, isLive);
                        if (isLive) {
                            var eventResultExtra = _cache.getEventResultExtra(tagEventResult[0]);
                            d['live-time'] = _template['time-live'].getText(d);
                            if (eventResultExtra) {
                                var period = eventResultExtra[2];
                                if (period > 0) {
                                    if (period == 5) {
                                        d['live-time'] = _template['time-halftime'].getText(d);
                                    } else {
                                        d['live-time'] = OddsUtility.getLiveTime(period, _cache.getLiveStartTime(tagEventResult[0]), eventResultExtra[3], eventResultExtra[4]);
                                        var injuryTime = parseInt('' + eventResultExtra[7], 10);
                                        if (injuryTime && injuryTime > 0) {
                                            d['injuryTimeCount'] = injuryTime;
                                            d['live-time'] += _template['injury-time'].getText(d);
                                        }
                                    }
                                }
                                var redCards = _cache.getRedCards(tagEventResult[0]);
                                var homeRedCards = '';
                                var awayRedCards = '';
                                var redCardCount;
                                if (redCards) {
                                    var redCardIndex;
                                    if (redCards.home <= 3) {
                                        for (redCardCount = 0; redCardCount < redCards.home; ++redCardCount) {
                                            homeRedCards += _template['red-card'].getText(d);
                                        }
                                        d['home-red-cards-no'] = redCards.home;
                                    } else {
                                        homeRedCards = _template['group-red-card'].getText({
                                            'red-card-count': redCards.home
                                        });
                                        d['home-red-cards-no'] = 'over';
                                    }
                                    if (redCards.away <= 3) {
                                        for (redCardCount = 0; redCardCount < redCards.away; ++redCardCount) {
                                            awayRedCards += _template['red-card'].getText(d);
                                        }
                                        d['away-red-cards-no'] = redCards.away;
                                    } else {
                                        awayRedCards = _template['group-red-card'].getText({
                                            'red-card-count': redCards.away
                                        });
                                        d['away-red-cards-no'] = 'over';
                                    }
                                } else {
                                    d['home-red-cards-no'] = 0;
                                    d['away-red-cards-no'] = 0;
                                }
                                d['home-red-cards'] = homeRedCards;
                                d['away-red-cards'] = awayRedCards;
                            }
                        } else {
                            OddsUtility.populateShowTime(d, event[6], usesLocalTime);
                            var showTimeType = event[5];
                            if (showTimeType & 0x8) {
                                d['showtime'] = _template['showtime-blue-live'].getText(d);
                            } else if (showTimeType & 0x4) {
                                d['showtime'] = _template['showtime-red-live'].getText(d);
                            } else if (showTimeType & 0x2) {
                                d['showtime'] = _template['showtime-date-time'].getText(d);
                            } else if (showTimeType & 0x1) {
                                d['showtime'] = _template['showtime-date-stars'].getText(d);
                            } else {
                                d['showtime'] = _template['showtime-date-time'].getText(d);
                            }
                        }
                    } else {
                        if (showSpecialRow) {
                            blocks.push(_template['special-row'].getText({}));
                            showSpecialRow = false;
                        }
                        isLive = event[8] == 0;
                        _populateSpecialMarkets(blocks, tagEventResult, isLive);
                    }
                }
                var eventInfo;
                if (isLive) {
                    eventInfo = _template['event-live-info'].getText(d);
                } else {
                    eventInfo = _template['event-nonlive-info'].getText(d);
                }
                d['event-info'] = eventInfo;
                var htmlWithData = blocks.join('');
                d['event-detail'] = htmlWithData;
                var ediv = document.getElementById('event-body-' + event[0]);
                if (!ediv) {
                    isRefreshProcessing = false;
                } else {
                    ediv.innerHTML = htmlWithData;
                    var idiv = document.getElementById('bu:ie:ev:' + event[0]);
                    if (idiv) {
                        if (isLive) {
                            idiv.innerHTML = _template['event-live-info'].getText(d);
                        } else {
                            idiv.innerHTML = _template['event-nonlive-info'].getText(d);
                        }
                    }
                }
                eventHTMLs.push(eventHTML.getText(d));
            }
        }
        if (_ignoreRefreshWay) {
            isRefreshProcessing = false;
        }
        d['refresh-count'] = _syn.refreshCount;
        if (isRefreshProcessing) {
            var rdiv = document.getElementById('bu:ie:r-refresh:button');
            if (rdiv) {
                rdiv.innerHTML = _syn.cooldownCount ? _template['refresh-refreshing'].getText(d) : _template['refresh-countdown'].getText(d);
            }
        } else {
            d['events'] = eventHTMLs.join('');
            d['refresh-button'] = _syn.cooldownCount ? _template['refresh-refreshing'].getText(d) : _template['refresh-countdown'].getText(d);
        }
        var div = document.getElementById('interested-event-view');
        if (div) {
            if (eventArray && eventArray.length > 0) {
                div.className = 'event-view';
                if (!isRefreshProcessing) {
                    div.innerHTML = _template['right-event-body'].getText(d);
                }
                _calculateMaxBodyHeight();
                var flag = 0;
                if (_expandingEventId) {
                    var eventBodyId = "event-body-" + _expandingEventId;
                    var eventBody = document.getElementById(eventBodyId);
                    if (eventBody) {
                        eventBody.style.display = "block";
                        TiLib.UI.addExpandEffect(eventBodyId, 200, _toggleEventComplete);
                        _expandedEventId = _expandingEventId;
                        _expandingEventId = 0;
                        flag = 1;
                    }
                }
                if (!flag) {
                    _applyScrollBar();
                }
            } else {
                div.className = 'event-view-hidden';
                div.innerHTML = '';
            }
        }
        _setEventBodyToExpanded();
    }

    function _setEventBodyToExpanded() {
        var fullbd = document.getElementById('event-fbody-' + _expandedEventId);
        if (fullbd) {
            fullbd.className = "event-view-repeat expanded";
        }
    }

    function _resetEventBodyToExpanded() {
        var fullbd = document.getElementById('event-fbody-' + _expandedEventId);
        if (fullbd) {
            fullbd.className = "event-view-repeat";
        }
    }

    function _populateMainMarkets(blocks, tagEventResult, isLive) {
        var eventResult = tagEventResult[2];
        var eventResultId = eventResult[0];
        var oddsByMarketDisplayId = tagEventResult[3];
        var marketGroup = tagEventResult[4];
        var event = tagEventResult[1];
        var oddsFTime1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTime1X2] : null;
        var oddsFHalf1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalf1X2] : null;
        var oddsFTimeLS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeLS] : null;
        var oddsFHalfLS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfLS] : null;
        var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
        var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
        var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
        var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
        var oddsFTimeOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOE] : null;
        var oddsFHalfOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOE] : null;
        var oddsFTimeCS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeCS] : null;
        var oddsFHalfCS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfCS] : null;
        var oddsHTFT = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.HTFT] : null;
        var oddsFGLG = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FGLG] : null;
        var oddsTG = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.TG] : null;
        var oddsML = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.ML] : null;
        var oddsDC = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.DC] : null;
        var homeScore = eventResult[3];
        var awayScore = eventResult[4];
        var i;
        var odds;
        var dd = {};
        var rows;
        var frozenCount = 0;
        _selectedOddId = $M('ticket').getOddIdOption(true);
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FTimeLS);
        if ((oddsFTimeLS && oddsFTimeLS.length > 0) || frozenCount > 0) {
            dd = {};
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            if (oddsFTimeLS) {
                odds = oddsFTimeLS[0];
                _populateOdds(dd, odds, _MarketDisplay.FTimeLS);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FTimeLS);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.FTimeLS)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['ft-ls-block-detail'].getText(dd);
            blocks.push(_template['ft-ls-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FHalfLS);
        if ((oddsFHalfLS && oddsFHalfLS.length > 0) || frozenCount > 0) {
            dd = {};
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            if (oddsFHalfLS) {
                odds = oddsFHalfLS[0];
                _populateOdds(dd, odds, _MarketDisplay.FHalfLS);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FHalfLS);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.FHalfLS)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['fh-ls-block-detail'].getText(dd);
            blocks.push(_template['fh-ls-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.ML);
        if ((oddsML && oddsML.length > 0) || frozenCount > 0) {
            dd = {};
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            if (oddsML) {
                odds = oddsML[0];
                _populateOdds(dd, odds, _MarketDisplay.ML);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.ML);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.ML)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['ml-block-detail'].getText(dd);
            blocks.push(_template['ml-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FTimeHDP);
        if ((oddsFTimeHDP && oddsFTimeHDP.length > 0) || frozenCount > 0) {
            rows = [];
            dd = {};
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            if (oddsFTimeHDP && oddsFTimeHDP.length > 0) {
                for (i = 0; i < oddsFTimeHDP.length; i++) {
                    odds = oddsFTimeHDP[i];
                    _populateOdds(dd, odds, _MarketDisplay.FTimeHDP);
                    rows.push(_template['ft-hdp-block-row'].getText(dd));
                }
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FTimeHDP);
                dd['frozen-odds'] = 'frozen-odds';
                rows.push(_template['ft-hdp-block-row'].getText(dd));
            }
            dd['rows'] = rows.join('');
            if (_isMarketClosed(eventResultId, _MarketDisplay.FTimeHDP)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['ft-hdp-block-detail'].getText(dd);
            blocks.push(_template['ft-hdp-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FHalfHDP);
        if ((oddsFHalfHDP && oddsFHalfHDP.length > 0) || frozenCount > 0) {
            rows = [];
            dd = {};
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            if (oddsFHalfHDP && oddsFHalfHDP.length > 0) {
                for (i = 0; i < oddsFHalfHDP.length; i++) {
                    odds = oddsFHalfHDP[i];
                    _populateOdds(dd, odds, _MarketDisplay.FHalfHDP);
                    rows.push(_template['fh-hdp-block-row'].getText(dd));
                }
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FHalfHDP);
                dd['frozen-odds'] = 'frozen-odds';
                rows.push(_template['fh-hdp-block-row'].getText(dd));
            }
            dd['rows'] = rows.join('');
            if (_isMarketClosed(eventResultId, _MarketDisplay.FHalfHDP)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['fh-hdp-block-detail'].getText(dd);
            blocks.push(_template['fh-hdp-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FTimeOU);
        if ((oddsFTimeOU && oddsFTimeOU.length > 0) || frozenCount > 0) {
            rows = [];
            dd = {};
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            if (oddsFTimeOU && oddsFTimeOU.length > 0) {
                for (i = 0; i < oddsFTimeOU.length; i++) {
                    odds = oddsFTimeOU[i];
                    _populateOdds(dd, odds, _MarketDisplay.FTimeOU);
                    rows.push(_template['ft-ou-block-row'].getText(dd));
                }
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FTimeOU);
                dd['frozen-odds'] = 'frozen-odds';
                rows.push(_template['ft-ou-block-row'].getText(dd));
            }
            dd['rows'] = rows.join('');
            if (_isMarketClosed(eventResultId, _MarketDisplay.FTimeOU)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['ft-ou-block-detail'].getText(dd);
            blocks.push(_template['ft-ou-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FHalfOU);
        if ((oddsFHalfOU && oddsFHalfOU.length > 0) || frozenCount > 0) {
            rows = [];
            dd = {};
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            if (oddsFHalfOU && oddsFHalfOU.length > 0) {
                for (i = 0; i < oddsFHalfOU.length; i++) {
                    odds = oddsFHalfOU[i];
                    _populateOdds(dd, odds, _MarketDisplay.FHalfOU);
                    rows.push(_template['fh-ou-block-row'].getText(dd));
                }
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FHalfOU);
                dd['frozen-odds'] = 'frozen-odds';
                rows.push(_template['fh-ou-block-row'].getText(dd));
            }
            dd['rows'] = rows.join('');
            if (_isMarketClosed(eventResultId, _MarketDisplay.FHalfOU)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['fh-ou-block-detail'].getText(dd);
            blocks.push(_template['fh-ou-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FTime1X2);
        if ((oddsFTime1X2 && oddsFTime1X2.length > 0) || frozenCount > 0) {
            dd = {};
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            if (oddsFTime1X2) {
                odds = oddsFTime1X2[0];
                _populateOdds(dd, odds, _MarketDisplay.FTime1X2);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FTime1X2);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.FTime1X2)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['ft-1x2-block-detail'].getText(dd);
            blocks.push(_template['ft-1x2-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FHalf1X2);
        if ((oddsFHalf1X2 && oddsFHalf1X2.length > 0) || frozenCount > 0) {
            dd = {};
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            if (oddsFHalf1X2) {
                odds = oddsFHalf1X2[0];
                _populateOdds(dd, odds, _MarketDisplay.FHalf1X2);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FHalf1X2);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.FHalf1X2)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['fh-1x2-block-detail'].getText(dd);
            blocks.push(_template['fh-1x2-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FTimeOE);
        if ((oddsFTimeOE && oddsFTimeOE.length > 0) || frozenCount > 0) {
            dd = {};
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            if (oddsFTimeOE) {
                odds = oddsFTimeOE[0];
                _populateOdds(dd, odds, _MarketDisplay.FTimeOE);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FTimeOE);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.FTimeOE)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['ft-oe-block-detail'].getText(dd);
            blocks.push(_template['ft-oe-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FHalfOE);
        if ((oddsFHalfOE && oddsFHalfOE.length > 0) || frozenCount > 0) {
            dd = {};
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            if (oddsFHalfOE) {
                odds = oddsFHalfOE[0];
                _populateOdds(dd, odds, _MarketDisplay.FHalfOE);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FHalfOE);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.FHalfOE)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['fh-oe-block-detail'].getText(dd);
            blocks.push(_template['fh-oe-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.TG);
        if ((oddsTG && oddsTG.length > 0) || frozenCount > 0) {
            dd = {};
            if (frozenCount > 0) {
                dd['frozen-odds-0'] = 'frozen-odds';
                dd['frozen-odds-1'] = 'frozen-odds';
                dd['frozen-odds-2'] = 'frozen-odds';
                dd['frozen-odds-3'] = 'frozen-odds';
            } else {
                if (oddsTG && oddsTG[0] && oddsTG[0][2] && oddsTG[0][2].length >= 4) {
                    dd['frozen-odds-0'] = oddsTG[0][2][0] > 1 ? 'cursor-pointer' : '';
                    dd['frozen-odds-1'] = oddsTG[0][2][1] > 1 ? 'cursor-pointer' : '';
                    dd['frozen-odds-2'] = oddsTG[0][2][2] > 1 ? 'cursor-pointer' : '';
                    dd['frozen-odds-3'] = oddsTG[0][2][3] > 1 ? 'cursor-pointer' : '';
                }
            }
            dd['event-result-id'] = eventResultId;
            if (oddsTG) {
                odds = oddsTG[0];
                _populateOdds(dd, odds, _MarketDisplay.TG);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.TG);
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.TG)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['tg-block-detail'].getText(dd);
            blocks.push(_template['tg-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.DC);
        if ((oddsDC && oddsDC.length > 0) || frozenCount > 0) {
            dd = {};
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            if (oddsDC) {
                odds = oddsDC[0];
                _populateOdds(dd, odds, _MarketDisplay.DC);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.DC);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.DC)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['dc-block-detail'].getText(dd);
            blocks.push(_template['dc-block'].getText(dd));
        }
        var price;
        var allPrices;
        var allPricesCount;
        var leftCol = [];
        var midCol = [];
        var rightCol = [];
        var rowCount = 0;
        var homeScoreOption;
        var awayScoreOption;
        var d;
        var priceIndicator;
        var rows;
        if (oddsFTimeCS && oddsFTimeCS.length > 0) {
            dd = {};
            dd['event-result-id'] = eventResultId;
            var selectedOddId = $M('ticket').getOddIdOption(true);
            rowCount = 0;
            leftCol = [];
            midCol = [];
            rightCol = [];
            rows = [];
            dd['home'] = TiLib.Text.encodeHTML(event[3]);
            dd['away'] = TiLib.Text.encodeHTML(event[4]);
            odds = oddsFTimeCS[0];
            if (isLive) {
                allPrices = odds[2];
                allPricesCount = allPrices.length;
                priceIndicator = _cache.getPriceAdjustIndicators(odds[0]);
                for (i = 0; i < allPricesCount; i++) {
                    price = allPrices[i];
                    if (price && price > 1) {
                        d = {};
                        homeScoreOption = (homeScore + parseInt(i / 5));
                        awayScoreOption = (awayScore + (i % 5));
                        if (i == allPricesCount - 1) {
                            d['cell-title'] = _template['title-cs-other'].getText(d);
                        } else {
                            d['cell-title'] = homeScoreOption.toFixed(0) + ':' + awayScoreOption.toFixed(0);
                        }
                        d['cell-text'] = OddsUtility.getPriceText(d, odds, _template['price-text'], i);
                        if (priceIndicator && priceIndicator[i]) {
                            d['cell-indicator'] = priceIndicator[i] > 0 ? 'price-up' : 'price-down';
                            d['cell-class'] = 'odds-change';
                        }
                        if (selectedOddId == d['odds-id'] + d['odds-option']) {
                            d['cell-class'] = 'odds-selected';
                        }
                        if ((i == allPricesCount - 1) || (homeScoreOption == awayScoreOption)) {
                            midCol.push(_template['live-cs-cell'].getText(d));
                        } else if (homeScoreOption > awayScoreOption) {
                            leftCol.push(_template['live-cs-cell'].getText(d));
                        } else {
                            rightCol.push(_template['live-cs-cell'].getText(d));
                        }
                    }
                }
                rowCount = leftCol.length;
                if (rowCount < midCol.length) {
                    rowCount = midCol.length;
                }
                if (rowCount < rightCol.length) {
                    rowCount = rightCol.length;
                }
                for (i = 0; i < rowCount; i++) {
                    d = {};
                    if (i < leftCol.length) {
                        d['left-cell'] = leftCol[i];
                    } else {
                        d['left-cell'] = _template['live-cs-empty-cell'].getText({});
                    }
                    if (i < midCol.length) {
                        d['mid-cell'] = midCol[i];
                    } else {
                        d['mid-cell'] = _template['live-cs-empty-cell'].getText({});
                    }
                    if (i < rightCol.length) {
                        d['right-cell'] = rightCol[i];
                    } else {
                        d['right-cell'] = _template['live-cs-empty-cell'].getText({});
                    }
                    rows.push(_template['live-ft-cs-row'].getText(d));
                }
                dd['rows'] = rows.join('');
                if (_isMarketClosed(eventResultId, _MarketDisplay.FTimeCS)) {
                    dd['style'] = 'display: none';
                }
                dd['detail'] = _template['live-ft-cs-block-detail'].getText(dd);
                blocks.push(_template['live-ft-cs-block'].getText(dd));
            } else {
                _populateOdds(dd, odds, _MarketDisplay.FTimeCS);
                if (_isMarketClosed(eventResultId, _MarketDisplay.FTimeCS)) {
                    dd['style'] = 'display: none';
                }
                dd['detail'] = _template['nonlive-ft-cs-block-detail'].getText(dd);
                blocks.push(_template['nonlive-ft-cs-block'].getText(dd));
            }
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FTimeCS);
        if (frozenCount > 0) {
            dd['home'] = TiLib.Text.encodeHTML(event[3]);
            dd['away'] = TiLib.Text.encodeHTML(event[4]);
            blocks.push(_template['live-ft-cs-frozen-block'].getText(dd));
        }
        var price;
        var allPrices;
        var allPricesCount;
        if (oddsFHalfCS && oddsFHalfCS.length > 0) {
            dd = {};
            dd['event-result-id'] = eventResultId;
            var selectedOddId = $M('ticket').getOddIdOption(true);
            rowCount = 0;
            leftCol = [];
            midCol = [];
            rightCol = [];
            rows = [];
            dd['home'] = TiLib.Text.encodeHTML(event[3]);
            dd['away'] = TiLib.Text.encodeHTML(event[4]);
            odds = oddsFHalfCS[0];
            if (isLive) {
                allPrices = odds[2];
                allPricesCount = allPrices.length;
                priceIndicator = _cache.getPriceAdjustIndicators(odds[0]);
                for (i = 0; i < allPricesCount; i++) {
                    price = allPrices[i];
                    if (price && price > 1) {
                        d = {};
                        homeScoreOption = (homeScore + parseInt(i / 4));
                        awayScoreOption = (awayScore + (i % 4));
                        if (i == allPricesCount - 1) {
                            d['cell-title'] = _template['title-cs-other'].getText(d);
                        } else {
                            d['cell-title'] = homeScoreOption.toFixed(0) + ':' + awayScoreOption.toFixed(0);
                        }
                        d['cell-text'] = OddsUtility.getPriceText(d, odds, _template['price-text'], i);
                        if (priceIndicator && priceIndicator[i]) {
                            d['cell-indicator'] = priceIndicator[i] > 0 ? 'price-up' : 'price-down';
                            d['cell-class'] = 'odds-change';
                        }
                        if (selectedOddId == d['odds-id'] + d['odds-option']) {
                            d['cell-class'] = 'odds-selected';
                        }
                        if ((i == allPricesCount - 1) || (homeScoreOption == awayScoreOption)) {
                            midCol.push(_template['live-cs-cell'].getText(d));
                        } else if (homeScoreOption > awayScoreOption) {
                            leftCol.push(_template['live-cs-cell'].getText(d));
                        } else {
                            rightCol.push(_template['live-cs-cell'].getText(d));
                        }
                    }
                }
                rowCount = leftCol.length;
                if (rowCount < midCol.length) {
                    rowCount = midCol.length;
                }
                if (rowCount < rightCol.length) {
                    rowCount = rightCol.length;
                }
                for (i = 0; i < rowCount; i++) {
                    d = {};
                    if (i < leftCol.length) {
                        d['left-cell'] = leftCol[i];
                    } else {
                        d['left-cell'] = _template['live-cs-empty-cell'].getText({});
                    }
                    if (i < midCol.length) {
                        d['mid-cell'] = midCol[i];
                    } else {
                        d['mid-cell'] = _template['live-cs-empty-cell'].getText({});
                    }
                    if (i < rightCol.length) {
                        d['right-cell'] = rightCol[i];
                    } else {
                        d['right-cell'] = _template['live-cs-empty-cell'].getText({});
                    }
                    rows.push(_template['live-fh-cs-row'].getText(d));
                }
                dd['rows'] = rows.join('');
                if (_isMarketClosed(eventResultId, _MarketDisplay.FHalfCS)) {
                    dd['style'] = 'display: none';
                }
                dd['detail'] = _template['live-fh-cs-block-detail'].getText(dd);
                blocks.push(_template['live-fh-cs-block'].getText(dd));
            } else {
                _populateOdds(dd, odds, _MarketDisplay.FHalfCS);
                if (_isMarketClosed(eventResultId, _MarketDisplay.FHalfCS)) {
                    dd['style'] = 'display: none';
                }
                dd['detail'] = _template['nonlive-fh-cs-block-detail'].getText(dd);
                blocks.push(_template['nonlive-fh-cs-block'].getText(dd));
            }
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FHalfCS);
        if (frozenCount > 0) {
            dd['home'] = TiLib.Text.encodeHTML(event[3]);
            dd['away'] = TiLib.Text.encodeHTML(event[4]);
            blocks.push(_template['live-fh-cs-frozen-block'].getText(dd));
        }
        if (oddsHTFT && oddsHTFT.length > 0) {
            dd = {};
            dd['event-result-id'] = eventResultId;
            odds = oddsHTFT[0];
            _populateOdds(dd, odds, _MarketDisplay.HTFT);
            if (_isMarketClosed(eventResultId, _MarketDisplay.HTFT)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['htft-block-detail'].getText(dd);
            blocks.push(_template['htft-block'].getText(dd));
        }
        if (oddsFGLG && oddsFGLG.length > 0) {
            dd = {};
            dd['event-result-id'] = eventResultId;
            dd['home'] = TiLib.Text.encodeHTML(event[3]);
            dd['away'] = TiLib.Text.encodeHTML(event[4]);
            odds = oddsFGLG[0];
            _populateOdds(dd, odds, _MarketDisplay.FGLG);
            if (_isMarketClosed(eventResultId, _MarketDisplay.FGLG)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['fglg-block-detail'].getText(dd);
            blocks.push(_template['fglg-block'].getText(dd));
        }
    }

    function _populateSpecialMarkets(blocks, tagEventResult, isLive) {
        var eventResult = tagEventResult[2];
        var eventResultId = eventResult[0];
        var oddsByMarketDisplayId = tagEventResult[3];
        var marketGroup = tagEventResult[4];
        var oddsFTime1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTime1X2] : null;
        var oddsFHalf1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalf1X2] : null;
        var oddsFTimeLS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeLS] : null;
        var oddsFHalfLS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfLS] : null;
        var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
        var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
        var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
        var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
        var oddsFTimeOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOE] : null;
        var oddsFHalfOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOE] : null;
        var oddsML = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.ML] : null;
        var i;
        var odds;
        var dd;
        var extOnly = (marketGroup[5]) ? '-extonly' : '';
        var homescore = eventResult[3];
        var awayscore = eventResult[4];
        _selectedOddId = $M('ticket').getOddIdOption(true);
        var frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FTimeLS);
        if ((oddsFTimeLS && oddsFTimeLS.length > 0) || frozenCount > 0) {
            dd = {};
            dd['dash'] = ' - ';
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            OddsUtility.populateMarketGroup(dd, marketGroup);
            OddsUtility.populateMarketGroupTeams(dd, marketGroup);
            if (oddsFTimeLS) {
                odds = oddsFTimeLS[0];
                _populateOdds(dd, odds, _MarketDisplay.FTimeLS);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FTimeLS);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.FTimeLS)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['ft-ls-block-detail'].getText(dd);
            if (isLive) {
                dd['live-score'] = _template['live-score-header'].getText({
                    'homescore': homescore,
                    'awayscore': awayscore
                });
            }
            blocks.push(_template['ft-ls-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FHalfLS);
        if ((oddsFHalfLS && oddsFHalfLS.length > 0) || frozenCount > 0) {
            dd = {};
            dd['dash'] = ' - ';
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            OddsUtility.populateMarketGroup(dd, marketGroup);
            OddsUtility.populateMarketGroupTeams(dd, marketGroup);
            if (oddsFHalfLS) {
                odds = oddsFHalfLS[0];
                _populateOdds(dd, odds, _MarketDisplay.FHalfLS);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FHalfLS);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.FHalfLS)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['fh-ls-block-detail'].getText(dd);
            if (isLive) {
                dd['live-score'] = _template['live-score-header'].getText({
                    'homescore': homescore,
                    'awayscore': awayscore
                });
            }
            blocks.push(_template['fh-ls-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.ML);
        if ((oddsML && oddsML.length > 0) || frozenCount > 0) {
            dd = {};
            dd['dash'] = ' - ';
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            OddsUtility.populateMarketGroup(dd, marketGroup);
            OddsUtility.populateMarketGroupTeams(dd, marketGroup);
            if (oddsML) {
                odds = oddsML[0];
                _populateOdds(dd, odds, _MarketDisplay.ML);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.ML);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.ML)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['ml-block-detail'].getText(dd);
            if (isLive) {
                dd['live-score'] = _template['live-score-header'].getText({
                    'homescore': homescore,
                    'awayscore': awayscore
                });
            }
            blocks.push(_template['ml-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FTimeHDP);
        if ((oddsFTimeHDP && oddsFTimeHDP.length > 0) || frozenCount > 0) {
            rows = [];
            dd = {};
            dd['dash'] = ' - ';
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            OddsUtility.populateMarketGroup(dd, marketGroup);
            OddsUtility.populateMarketGroupTeams(dd, marketGroup);
            if (oddsFTimeHDP && oddsFTimeHDP.length > 0) {
                for (i = 0; i < oddsFTimeHDP.length; i++) {
                    odds = oddsFTimeHDP[i];
                    _populateOdds(dd, odds, _MarketDisplay.FTimeHDP);
                    rows.push(_template['ft-hdp' + extOnly + '-block-row'].getText(dd));
                }
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FTimeHDP);
                dd['frozen-odds'] = 'frozen-odds';
                rows.push(_template['ft-hdp' + extOnly + '-block-row'].getText(dd));
            }
            dd['rows'] = rows.join('');
            if (_isMarketClosed(eventResultId, _MarketDisplay.FTimeHDP)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['ft-hdp' + extOnly + '-block-detail'].getText(dd);
            if (isLive) {
                dd['live-score'] = _template['live-score-header'].getText({
                    'homescore': homescore,
                    'awayscore': awayscore
                });
            }
            blocks.push(_template['ft-hdp' + extOnly + '-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FHalfHDP);
        if ((oddsFHalfHDP && oddsFHalfHDP.length > 0) || frozenCount > 0) {
            rows = [];
            dd = {};
            dd['dash'] = ' - ';
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            OddsUtility.populateMarketGroup(dd, marketGroup);
            OddsUtility.populateMarketGroupTeams(dd, marketGroup);
            if (oddsFHalfHDP && oddsFHalfHDP.length > 0) {
                for (i = 0; i < oddsFHalfHDP.length; i++) {
                    odds = oddsFHalfHDP[i];
                    _populateOdds(dd, odds, _MarketDisplay.FHalfHDP);
                    rows.push(_template['fh-hdp' + extOnly + '-block-row'].getText(dd));
                }
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FHalfHDP);
                dd['frozen-odds'] = 'frozen-odds';
                rows.push(_template['fh-hdp' + extOnly + '-block-row'].getText(dd));
            }
            dd['rows'] = rows.join('');
            if (_isMarketClosed(eventResultId, _MarketDisplay.FHalfHDP)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['fh-hdp' + extOnly + '-block-detail'].getText(dd);
            if (isLive) {
                dd['live-score'] = _template['live-score-header'].getText({
                    'homescore': homescore,
                    'awayscore': awayscore
                });
            }
            blocks.push(_template['fh-hdp' + extOnly + '-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FTimeOU);
        if ((oddsFTimeOU && oddsFTimeOU.length > 0) || frozenCount > 0) {
            rows = [];
            dd = {};
            dd['dash'] = ' - ';
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            OddsUtility.populateMarketGroup(dd, marketGroup);
            OddsUtility.populateMarketGroupTeams(dd, marketGroup);
            if (oddsFTimeOU && oddsFTimeOU.length > 0) {
                for (i = 0; i < oddsFTimeOU.length; i++) {
                    odds = oddsFTimeOU[i];
                    _populateOdds(dd, odds, _MarketDisplay.FTimeOU);
                    rows.push(_template['ft-ou-block-row'].getText(dd));
                }
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FTimeOU);
                dd['frozen-odds'] = 'frozen-odds';
                rows.push(_template['ft-ou-block-row'].getText(dd));
            }
            dd['rows'] = rows.join('');
            if (_isMarketClosed(eventResultId, _MarketDisplay.FTimeOU)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['ft-ou-block-detail'].getText(dd);
            if (isLive) {
                dd['live-score'] = _template['live-score-header'].getText({
                    'homescore': homescore,
                    'awayscore': awayscore
                });
            }
            blocks.push(_template['ft-ou-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FHalfOU);
        if ((oddsFHalfOU && oddsFHalfOU.length > 0) || frozenCount > 0) {
            rows = [];
            dd = {};
            dd['dash'] = ' - ';
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            OddsUtility.populateMarketGroup(dd, marketGroup);
            OddsUtility.populateMarketGroupTeams(dd, marketGroup);
            if (oddsFHalfOU && oddsFHalfOU.length > 0) {
                for (i = 0; i < oddsFHalfOU.length; i++) {
                    odds = oddsFHalfOU[i];
                    _populateOdds(dd, odds, _MarketDisplay.FHalfOU);
                    rows.push(_template['fh-ou-block-row'].getText(dd));
                }
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FHalfOU);
                dd['frozen-odds'] = 'frozen-odds';
                rows.push(_template['fh-ou-block-row'].getText(dd));
            }
            dd['rows'] = rows.join('');
            if (_isMarketClosed(eventResultId, _MarketDisplay.FHalfOU)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['fh-ou-block-detail'].getText(dd);
            if (isLive) {
                dd['live-score'] = _template['live-score-header'].getText({
                    'homescore': homescore,
                    'awayscore': awayscore
                });
            }
            blocks.push(_template['fh-ou-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FTime1X2);
        if ((oddsFTime1X2 && oddsFTime1X2.length > 0) || frozenCount > 0) {
            dd = {};
            dd['dash'] = ' - ';
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            OddsUtility.populateMarketGroup(dd, marketGroup);
            OddsUtility.populateMarketGroupTeams(dd, marketGroup);
            if (oddsFTime1X2) {
                odds = oddsFTime1X2[0];
                _populateOdds(dd, odds, _MarketDisplay.FTime1X2);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FTime1X2);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.FTime1X2)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['ft-1x2-block-detail'].getText(dd);
            if (isLive) {
                dd['live-score'] = _template['live-score-header'].getText({
                    'homescore': homescore,
                    'awayscore': awayscore
                });
            }
            blocks.push(_template['ft-1x2-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FHalf1X2);
        if ((oddsFHalf1X2 && oddsFHalf1X2.length > 0) || frozenCount > 0) {
            dd = {};
            dd['dash'] = ' - ';
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            OddsUtility.populateMarketGroup(dd, marketGroup);
            OddsUtility.populateMarketGroupTeams(dd, marketGroup);
            if (oddsFHalf1X2) {
                odds = oddsFHalf1X2[0];
                _populateOdds(dd, odds, _MarketDisplay.FHalf1X2);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FHalf1X2);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.FHalf1X2)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['fh-1x2-block-detail'].getText(dd);
            if (isLive) {
                dd['live-score'] = _template['live-score-header'].getText({
                    'homescore': homescore,
                    'awayscore': awayscore
                });
            }
            blocks.push(_template['fh-1x2-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FTimeOE);
        if ((oddsFTimeOE && oddsFTimeOE.length > 0) || frozenCount > 0) {
            dd = {};
            dd['dash'] = ' - ';
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            OddsUtility.populateMarketGroup(dd, marketGroup);
            OddsUtility.populateMarketGroupTeams(dd, marketGroup);
            if (oddsFTimeOE) {
                odds = oddsFTimeOE[0];
                _populateOdds(dd, odds, _MarketDisplay.FTimeOE);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FTimeOE);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.FTimeOE)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['ft-oe-block-detail'].getText(dd);
            if (isLive) {
                dd['live-score'] = _template['live-score-header'].getText({
                    'homescore': homescore,
                    'awayscore': awayscore
                });
            }
            blocks.push(_template['ft-oe-block'].getText(dd));
        }
        frozenCount = _cache.getFrozenOddsCount(eventResultId, _MarketDisplay.FHalfOE);
        if ((oddsFHalfOE && oddsFHalfOE.length > 0) || frozenCount > 0) {
            dd = {};
            dd['dash'] = ' - ';
            dd['frozen-odds'] = 'cursor-pointer';
            dd['event-result-id'] = eventResultId;
            OddsUtility.populateMarketGroup(dd, marketGroup);
            OddsUtility.populateMarketGroupTeams(dd, marketGroup);
            if (oddsFHalfOE) {
                odds = oddsFHalfOE[0];
                _populateOdds(dd, odds, _MarketDisplay.FHalfOE);
            } else if (frozenCount > 0) {
                _populateOdds(dd, null, _MarketDisplay.FHalfOE);
                dd['frozen-odds'] = 'frozen-odds';
            }
            if (_isMarketClosed(eventResultId, _MarketDisplay.FHalfOE)) {
                dd['style'] = 'display: none';
            }
            dd['detail'] = _template['fh-oe-block-detail'].getText(dd);
            if (isLive) {
                dd['live-score'] = _template['live-score-header'].getText({
                    'homescore': homescore,
                    'awayscore': awayscore
                });
            }
            blocks.push(_template['fh-oe-block'].getText(dd));
        }
    }

    function _drawRefreshButtons() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        a = document.getElementById('bu:ie:r-refresh:button');
        if (a) {
            if (_syn.cooldownCount) {
                a.innerHTML = _template['refresh-refreshing'].getText();
            } else if (a.isHover) {
                a.innerHTML = _template['refresh-hover'].getText();
            } else {
                a.innerHTML = _template['refresh-countdown'].getText({
                    'refresh-count': _syn.refreshCount
                });
            }
        }
    }

    function _populateOdds(d, odds, marketDisplayId) {
        if (odds) {
            OddsUtility.populateOdds(d, odds, _template['price-text'], _cache.getPriceAdjustIndicators(odds[0]), null, null, _selectedOddId);
            OddsUtility.populateOddsPoints(d, odds);
            OddsUtility.populateOddsLabels(d, odds);
            OddsUtility.populateOddsIndicators(d, odds, _cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
        } else {
            OddsUtility.clearOdds(d, marketDisplayId);
            OddsUtility.clearOddsPoints(d, marketDisplayId);
            OddsUtility.clearOddsLabels(d, marketDisplayId);
            OddsUtility.clearOddsIndicators(d, marketDisplayId);
        }
    }
}

function __Module_SelectTournament() {
    var _TemplateName = 'odds-display/select-tournament';
    var _self = this;
    var _template = null;
    var _frameIndex = -1;
    var _cache = new __Cache_SelectTournament();
    var _sportId = null;
    var _syn = {
        waitingTemplate: false
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_syn.waitingTemplate) {
                    if (_template) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                }
            }
        }
    };
    this.onOpen = function (data, fi) {
        _frameIndex = fi;
        _cache.update(data);
        _draw();
        var div = document.getElementById('div-popup');
        if (div) {
            div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            var topPosition = TiLib.Document.getScrollHeight() + (TiLib.Document.getInnerHeight() / 2);
            var leftPosition = TiLib.Document.getScrollWidth() + (TiLib.Document.getInnerWidth() / 2);
            div.style.position = 'absolute';
            div.style.top = topPosition + 'px';
            div.style.left = leftPosition + 'px';
            div.style.zIndex = 9999;
            var mask = document.getElementById('popup-mask');
            if (mask) {
                mask.className = 'popup-mask';
            }
        }
        ScrollDiv.draw('select-tournament-id', 400);
    };
    this.onClose = function (frameIndex) {
        var div = document.getElementById('div-popup');
        if (div) {
            div.className = TiLib.Text.addClassItem(div.className, 'hide');
        }
        var allDates = 8;
        $M('odds-display').setDisplaySetting('event-date', allDates);
        if (frameIndex != undefined) {
            if (frameIndex == 0) {
                $M('odds-display').refreshLive(true);
            } else {
                $M('odds-display').refreshNonlive(true);
            }
        } else {
            $M('odds-display').refresh(true);
        }
        if ($M('global') && $M('global').enablePageScroll) {
            $M('global').enablePageScroll();
        }
        var mask = document.getElementById('popup-mask');
        if (mask) {
            mask.className = '';
        }
        TiLib.Event.removeListener('mousedown', _onMouseDown);
        TiLib.Event.removeListener('keydown', _onKeyDown);
    };
    this.toggleNoFilter = function () {
        _cache.setNoFilter(_cache.isNoFilter() ? 0 : 1);
        _draw();
    };
    this.selectAll = function () {
        _cache.selectAllTournaments();
        _draw();
    };
    this.deselectAll = function () {
        _cache.deselectAllTournaments();
        _draw();
    };
    this.onSelect = function (tournamentId) {
        var input = document.getElementById('st-' + tournamentId);
        _cache.selectTournament(tournamentId, input.checked);
    };
    this.submit = function () {
        if (_cache.isNoFilter()) {
            var url = [];
            url.push('odds-display/select-tournament-data.aspx?req=submit&nofilter=1&od-param=');
            url.push($M('odds-display').getOddsDisplayParam());
            url.push('&fi=' + _frameIndex);
            if (_sportId) {
                url.push('&sportId=' + _sportId);
                _sportId = null;
            }
            TiLib.Ajax.sendRequest('select-tournament', url.join(''));
        } else {
            var sb = [];
            var tournaments = _cache.getTournamentArray();
            var c = tournaments.length;
            for (var i = 0; i < c; ++i) {
                var tournament = tournaments[i];
                if (tournament[2]) {
                    sb.push(tournament[0]);
                }
            }
            if (sb.length > 0) {
                var url = [];
                url.push('odds-display/select-tournament-data.aspx?req=submit&od-param=');
                url.push($M('odds-display').getOddsDisplayParam());
                url.push('&fi=' + _frameIndex);
                if (_sportId) {
                    url.push('&sportId=' + _sportId);
                    _sportId = null;
                }
                TiLib.Ajax.postRequest('select-tournament', url.join(''), 'ids=' + sb.join(','));
            } else {
                alert(_template['no-tournament-selected'].getText());
            }
        }
    };
    this.cancel = function () {
        var div = document.getElementById('div-popup');
        if (div) {
            div.className = TiLib.Text.addClassItem(div.className, 'hide');
        }
        if ($M('global') && $M('global').enablePageScroll) {
            $M('global').enablePageScroll();
        }
        var mask = document.getElementById('popup-mask');
        if (mask) {
            mask.className = '';
        }
        TiLib.Event.removeListener('mousedown', _onMouseDown);
        TiLib.Event.removeListener('keydown', _onKeyDown);
    };
    this.open = function (frameIndex, sportId, date) {
        if (!frameIndex) frameIndex = 0;
        _frameIndex = frameIndex;
        if (_template == null) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
            }
        }
        var sb = [];
        sb.push('odds-display/select-tournament-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=');
        sb.push(_frameIndex);
        if (sportId) {
            sb.push('&sportId=' + sportId);
            _sportId = sportId;
        }
        if (date) {
            sb.push('&date=' + date);
        }
        return TiLib.Ajax.sendRequest('select-tournament', sb.join(''));
    };
    this.refresh = function () {
        var sb = [];
        sb.push('odds-display/select-tournament-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=');
        sb.push(_frameIndex);
        return TiLib.Ajax.sendRequest('select-tournament', sb.join(''));
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var tournaments = _cache.getTournamentArray();
        var c = tournaments.length;
        var i = 0;
        var d = {};
        var rows = [];
        while (i < c) {
            d['cell-0'] = _getTournamentCell(d, tournaments[i++], i);
            d['cell-1'] = _getTournamentCell(d, tournaments[i++], i);
            d['cell-2'] = _getTournamentCell(d, tournaments[i++], i);
            rows.push(_template['row'].getText(d));
        }
        d['rows'] = rows.length > 0 ? rows.join('') : _template['row-nodata'].getText();
        d['none-hide'] = rows.length > 0 ? 'hide' : '';
        d['inner-hide'] = rows.length > 0 ? '' : 'hide';
        d['table'] = _template[_cache.isNoFilter() ? 'table-nofilter' : 'table'].getText(d);
        d['nofilter'] = _template[_cache.isNoFilter() ? 'nofilter-checked' : 'nofilter'].getText(d);
        var block = _template['block'].getText(d);
        var div = document.getElementById('div-popup');
        if (div) {
            var topPosition = TiLib.Document.getScrollHeight() + (TiLib.Document.getInnerHeight() / 2);
            var leftPosition = TiLib.Document.getScrollWidth() + (TiLib.Document.getInnerWidth() / 2);
            div.style.position = 'absolute';
            div.style.top = topPosition + 'px';
            div.style.left = leftPosition + 'px';
            div.style.zIndex = 9999;
            var mask = document.getElementById('popup-mask');
            if (mask) {
                mask.className = 'popup-mask';
            }
            div.innerHTML = block;
        }
        var input = document.getElementById('nofilter');
        if (input) {
            input.checked = _cache.isNoFilter() ? true : false;
        }
        if ($M('global') && $M('global').disablePageScroll) {
            $M('global').disablePageScroll();
        }
        TiLib.Event.addListener('mousedown', _onMouseDown);
        TiLib.Event.addListener('keydown', _onKeyDown);
        ScrollDiv.draw('select-tournament-id', 400);
    }

    function _getTournamentCell(d, tournament, i) {
        if (tournament) {
            d['tournament-id'] = tournament[0];
            d['tournament'] = TiLib.Text.encodeHTML(tournament[1]);
            if (_cache.isNoFilter()) {
                d['tab-index'] = -1;
                return _template['cell-disabled'].getText(d);
            } else if (tournament[2]) {
                d['tab-index'] = 10 + i;
                return _template['cell-selected'].getText(d);
            } else {
                d['tab-index'] = 10 + i;
                return _template['cell-unselected'].getText(d);
            }
        } else {
            return _template['cell-empty'].getText(d);
        }
    };

    function _onKeyDown(event) {
        if (event.keyCode == 27) {
            $M('select-tournament').cancel();
        }
    }

    function _onMouseDown(event) {
        var e = event;
        var node = (e.target || e.srcElement);
        var isWithinArea = true;
        while (node) {
            if (node.id == 'popup-mask') {
                isWithinArea = false;
                break;
            }
            node = node.parentNode;
        }
        if (!isWithinArea) {
            $M('select-tournament').cancel();
        }
        true;
    }
}

function __Cache_More() {
    var _isLive = false;
    var _event = null;
    var _eventResultDictionary = {};
    var _oddsDictionary = {};
    var _marketGroupDictionary = {};
    var _tagEventResultDictionary = {};
    var _tagEventResultArray = [];
    var _priceAdjustIndicators = null;
    this.update = function (data, clearAll, priceStyle) {
        var isChanged = false;
        _priceAdjustIndicators = null;
        if (clearAll || _isLive != data[0]) {
            isChanged = true;
            _event = null;
            _eventResultDictionary = {};
            _oddsDictionary = {};
            _marketGroupDictionary = {};
        }
        if (data) {
            _isLive = data[0];
            if (data[1]) {
                isChanged = true;
                _event = data[1];
            }
            if (data[2]) {
                isChanged = true;
                _updateElements(_eventResultDictionary, data[2]);
            }
            if (data[3]) {
                isChanged = true;
                _updateOdds(_oddsDictionary, data[3], priceStyle);
            }
            if (data[4]) {
                isChanged = true;
                _updateElements(_marketGroupDictionary, data[4]);
            }
            if (data[5]) {
                isChanged = true;
                _deleteElements(_oddsDictionary, data[5]);
            }
        }
        _normalize();
        return isChanged;
    };
    this.isLive = function () {
        return _isLive;
    };
    this.getEvent = function () {
        return _event;
    };
    this.getTagEventResultArray = function () {
        return _tagEventResultArray;
    };
    this.getPriceAdjustIndicators = function (oddsId) {
        return (_priceAdjustIndicators && _priceAdjustIndicators[oddsId]) ? _priceAdjustIndicators[oddsId] : [];
    };
    this.clearAdjustIndicators = function () {
        if (_priceAdjustIndicators) {
            _priceAdjustIndicators = null;
            return true;
        } else {
            return false;
        }
    };

    function _updateOdds(oddsDictionary, oddsArray, priceStyle) {
        if (!oddsArray) return;
        var c = oddsArray.length;
        for (var i = 0; i < c; ++i) {
            var odds = oddsArray[i];
            if (!odds) continue;
            var oddsId = odds[0];
            var oldOdds = oddsDictionary[oddsId];
            if (oldOdds) {
                odds = oldOdds.updateArray(odds);
                var oldPrices = oldOdds[2];
                var newPrices = odds[2];
                var priceCount = newPrices.length;
                for (var priceIndex = 0; priceIndex < priceCount; ++priceIndex) {
                    var indicator = 0;
                    var oldPrice = oldPrices[priceIndex];
                    var newPrice = newPrices[priceIndex];
                    if (oldPrice == newPrice) continue;
                    if (priceStyle == 3) {
                        indicator = (newPrice > oldPrice) ? 1 : -1;
                    } else {
                        if (oldPrice > 0) {
                            if (newPrice > 0) {
                                indicator = (newPrice > oldPrice) ? 1 : -1;
                            } else {
                                indicator = 1;
                            }
                        } else if (oldPrice < 0) {
                            if (newPrice > 0) {
                                indicator = -1;
                            } else {
                                indicator = (newPrice > oldPrice) ? 1 : -1;
                            }
                        } else {
                            if (newPrice > 0) {
                                indicator = -2;
                            } else {
                                indicator = (newPrice > oldPrice) ? 1 : -1;
                            }
                        }
                    }
                    if (indicator != 0) {
                        if (!_priceAdjustIndicators) {
                            _priceAdjustIndicators = {};
                        }
                        var indicators = _priceAdjustIndicators[oddsId];
                        if (!indicators) {
                            indicators = [];
                            _priceAdjustIndicators[oddsId] = indicators;
                        }
                        indicators[priceIndex] = indicator;
                    }
                }
            }
            oddsDictionary[oddsId] = odds;
        }
    }

    function _updateElements(elementDictionary, elementArray) {
        if (!elementArray) return;
        var c = elementArray.length;
        for (var i = 0; i < c; ++i) {
            var element = elementArray[i];
            if (!element) continue;
            var elementId = element[0];
            var oldElement = elementDictionary[elementId];
            if (oldElement) {
                element = oldElement.updateArray(element);
            }
            elementDictionary[elementId] = element;
        }
    }

    function _deleteElements(elementDictionary, elementIdArray) {
        if (!elementIdArray) return;
        var c = elementIdArray.length;
        for (var i = 0; i < c; ++i) {
            var elementId = elementIdArray[i];
            if (!elementId) continue;
            delete elementDictionary[elementId];
        }
    }

    function _normalize() {
        var oddsByEventResultId = {};
        for (var oddsId in _oddsDictionary) {
            var odds = _oddsDictionary[oddsId];
            var eventResultId = odds[1][0];
            var eventResult = _eventResultDictionary[eventResultId];
            if (!eventResult) {
                delete _oddsDictionary[oddsId];
                continue;
            }
            var oddsByMarketDisplayId = oddsByEventResultId[eventResultId];
            if (!oddsByMarketDisplayId) {
                oddsByMarketDisplayId = {};
                oddsByEventResultId[eventResultId] = oddsByMarketDisplayId;
            }
            var marketDisplayId = odds[1][1];
            var oddsArray = oddsByMarketDisplayId[marketDisplayId];
            if (!oddsArray) {
                oddsArray = [];
                oddsByMarketDisplayId[marketDisplayId] = oddsArray;
            }
            oddsArray.push(odds);
        }
        for (eventResultId in oddsByEventResultId) {
            oddsByMarketDisplayId = oddsByEventResultId[eventResultId];
            for (marketDisplayId in oddsByMarketDisplayId) {
                oddsArray = oddsByMarketDisplayId[marketDisplayId];
                oddsArray.sort(_sortOddsCallback);
            }
        }
        var normalizedMarketGroupDiciionary = {};
        for (var marketGroupId in _marketGroupDictionary) {
            var marketGroup = _marketGroupDictionary[marketGroupId];
            var normalizedMarketGroup = marketGroup.updateArray(marketGroup, []);
            normalizedMarketGroup[2] = TiLib.Template.createTemplate(normalizedMarketGroup[2]);
            normalizedMarketGroup[3] = TiLib.Template.createTemplate(normalizedMarketGroup[3]);
            normalizedMarketGroupDiciionary[marketGroupId] = normalizedMarketGroup;
        }
        _tagEventResultDictionary = {};
        _tagEventResultArray = [];
        var deletedEventResultIds = [];
        for (eventResultId in _eventResultDictionary) {
            eventResult = _eventResultDictionary[eventResultId];
            if (!eventResult) continue;
            oddsByMarketDisplayId = oddsByEventResultId[eventResultId];
            if (!oddsByMarketDisplayId) continue;
            marketGroupId = eventResult[2];
            marketGroup = normalizedMarketGroupDiciionary[marketGroupId];
            var tagEventResult = [eventResultId, _event, eventResult, oddsByMarketDisplayId, marketGroup];
            _tagEventResultDictionary[eventResultId] = tagEventResult;
            _tagEventResultArray.push(tagEventResult);
        }
        _tagEventResultArray.sort(_sortTagEventResultCallback);
    }

    function _sortTagEventResultCallback(tagEventResult1, tagEventResult2) {
        var eventResult1 = tagEventResult1[2];
        var eventResult2 = tagEventResult2[2];
        var marketGroup1 = tagEventResult1[4];
        var marketGroup2 = tagEventResult2[4];
        if (marketGroup1 && marketGroup2) {
            if (marketGroup1[4] != marketGroup2[4]) {
                return marketGroup1[4] - marketGroup2[4];
            }
        } else if (marketGroup1) {
            return 1;
        } else if (marketGroup2) {
            return -1;
        }
        return eventResult1[0] - eventResult2[0];
    }

    function _sortOddsCallback(odds1, odds2) {
        var maxbet1 = odds1[1][3];
        var maxbet2 = odds2[1][3];
        if (maxbet1 != maxbet2) {
            return (maxbet1 > maxbet2) ? -1 : 1;
        }
        return (odds1[0] < odds2[0]) ? -1 : 1;
    }
}

function __Module_More(refreshRate) {
    var _MarketDisplay = {
        FTimeHDP: 1,
        FTimeOE: 2,
        FTimeOU: 3,
        FTimeCS: 4,
        FTime1X2: 5,
        TG: 6,
        FHalfHDP: 7,
        FHalf1X2: 8,
        FHalfOU: 9,
        HTFT: 10,
        ML: 11,
        FHalfOE: 12,
        FGLG: 13,
        FHalfCS: 14,
        DC: 15,
        FTimeLS: 16,
        FHalfLS: 17
    };
    var _TemplateName = 'odds-display/more';
    var _template = null;
    var _moreBlockInfo = [0, 0];
    var _closingMoreBlockInfo = [0, 0];
    var _currentContentCache = '';
    var _selectedOddId = null;
    var _self = this;
    var _dataParam = null;
    var _cache = new __Cache_More();
    var _syn = {
        waitingTemplate: false
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
    };
    this.isMoreOpened = function (eventResultId, frameIndex) {
        return _moreBlockInfo[0] == eventResultId && _moreBlockInfo[1] == frameIndex;
    };
    this.isLiveMoreOpened = function () {
        return _moreBlockInfo && _moreBlockInfo[0] > 0 && _moreBlockInfo[1] == 0;
    };
    this.isClosing = function (eventResultId, frameIndex) {
        return _closingMoreBlockInfo[0] == eventResultId && _closingMoreBlockInfo[1] == frameIndex;
    };
    this.getContent = function (colSpan) {
        return _getContent(colSpan);
    };
    this.getClosingContent = function () {
        return _currentContentCache;
    };
    this.getMoreParam = function (isLive) {
        if ((isLive && _moreBlockInfo[1] == 0) || (!isLive && _moreBlockInfo[1] == 1)) {
            if (_moreBlockInfo[0] > 0) {
                return '&more=' + _moreBlockInfo[0];
            }
        }
        return '';
    };
    this.clearMoreBlockInfo = function () {
        _closingMoreBlockInfo = [0, 0];
        _moreBlockInfo = [0, 0];
    };
    this.closeMoreBlock = function () {
        _closingMoreBlockInfo = _moreBlockInfo;
        _moreBlockInfo = [0, 0];
        _dataParam = null;
        _onClosingMoreComplete();
    };
    this.openMoreBlock = function (eventResultId, frameIndex, marketFrameId) {
        _closingMoreBlockInfo = _moreBlockInfo;
        _moreBlockInfo = [eventResultId, frameIndex];
        var eventLevel = ($M('odds-display').getDisplaySetting('market-showing') == 1 || frameIndex == 1) ? 1 : 0;
        if (eventResultId > 0) {
            _open(marketFrameId, eventResultId, eventLevel);
        }
    };
    this.refresh = function (marketFrameId) {
        if (_moreBlockInfo && _moreBlockInfo[0] > 0) {
            var eventResultId = _moreBlockInfo[0];
            var frameIndex = _moreBlockInfo[1];
            var eventLevel = ($M('odds-display').getDisplaySetting('market-showing') == 1 || frameIndex == 1) ? 1 : 0;
            if (eventResultId > 0) {
                _open(marketFrameId, eventResultId, eventLevel);
            }
        }
    };

    function _onClosingMoreComplete() {
        _closingMoreBlockInfo = [0, 0];
        _currentContentCache = '';
        _draw();
    };

    function _onOpeningMoreComplete() {
        _currentContentCache = '';
        _closingMoreBlockInfo = [0, 0];
        _draw();
    };

    function _open(marketFrameId, eventResultId, isEventLevel) {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        _dataParam = TiLib.Parameter.createParameter(['market-frame', 'event-result-id', 'event-level', 'price-style'], [marketFrameId, eventResultId, isEventLevel, $M('odds-display').getDisplaySetting('price-style')]);
        _submit();
    }

    function _submit() {
        var sb = [];
        sb.push('odds-display/more-data.aspx?param=');
        sb.push(_dataParam.getJoinedValues());
        return TiLib.Ajax.sendRequest('more', sb.join(''));
    }
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_syn.waitingTemplate) {
                    if (_template) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                }
            }
        }
    };
    this.onIdle = function (version) {
        if (_cache.clearAdjustIndicators()) {
            _draw();
        }
    };
    this.onUpdate = function (data, forceDraw) {
        if (!data || !_dataParam) return;
        if (_dataParam.getValue('price-style') != $M('odds-display').getDisplaySetting('price-style')) {
            _cache.update(data, true, $M('odds-display').getDisplaySetting('price-style'));
        } else {
            _cache.update(data, false, $M('odds-display').getDisplaySetting('price-style'));
        }
        _dataParam.setValue('price-style', $M('odds-display').getDisplaySetting('price-style'));
        if (forceDraw) {
            _draw();
        }
    };
    this.onOpen = function (data) {
        if (!data || !_dataParam) return;
        _cache.update(data, true);
        _onOpeningMoreComplete();
    };

    function _draw() {
        $M('odds-display').draw();
    }

    function _getContent(colSpan) {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var content = '';
        var d = {};
        d['event-result-id'] = _moreBlockInfo[0];
        d['frame-index'] = _moreBlockInfo[1];
        var tagEventResults = _cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var blocks = [];
        var specialBlocks = [];
        if (_dataParam.getValue('market-frame') == 20) {
            d['price-or-mpprice'] = 'mpprice';
        } else {
            d['price-or-mpprice'] = 'price';
        }
        var event = _cache.getEvent();
        if (!event) return;
        _populateEvent(d, event);
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var marketGroup = tagEventResult[4];
            if (!marketGroup || marketGroup[0] == 0) {
                _populateMainMarkets(blocks, d, tagEventResult);
            } else {
                OddsUtility.populateMarketGroup(d, marketGroup);
                OddsUtility.populateMarketGroupTeams(d, marketGroup);
                if (marketGroup[6]) {
                    _populateSpecialMarkets(specialBlocks, d, tagEventResult);
                } else {
                    _populateSpecialDoubleMarkets(specialBlocks, d, tagEventResult);
                }
            }
        }
        if (specialBlocks.length > 0) {
            blocks = blocks.concat(specialBlocks);
        }
        d['col-span'] = colSpan;
        if (blocks.length > 0) {
            var allBlock = [];
            var index = 0;
            for (var i = 0; i < blocks.length; i += 2) {
                var widthWeight = blocks[i];
                var block = blocks[i + 1];
                if (isNaN(widthWeight)) {
                    continue;
                }
                index += widthWeight;
                if (index >= 3) {
                    if (Math.ceil(index) % 3 > 0) {
                        allBlock.push(_template['br-all'].getText());
                        allBlock.push(block);
                        index = widthWeight;
                    } else if (Math.ceil(index) % 3 == 0) {
                        allBlock.push(block);
                        allBlock.push(_template['br-all'].getText());
                        index = 0;
                    }
                } else {
                    allBlock.push(block);
                }
            }
            d['more-blocks'] = allBlock.join('');
            content = _template['more-row'].getText(d);
        } else if (_moreBlockInfo[0] > 0) {
            content = '';
        } else {
            content = _template['more-row-nodata'].getText(d);
        }
        if (_closingMoreBlockInfo[0] <= 0) {
            _currentContentCache = content;
        }
        return content;
    }

    function _populateMainMarkets(blocks, d, tagEventResult) {
        var eventResult = tagEventResult[2];
        var eventResultId = eventResult[0];
        var oddsByMarketDisplayId = tagEventResult[3];
        var marketGroup = tagEventResult[4];
        var oddsFTime1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTime1X2] : null;
        var oddsFHalf1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalf1X2] : null;
        var oddsFTimeLS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeLS] : null;
        var oddsFHalfLS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfLS] : null;
        var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
        var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
        var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
        var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
        var oddsFTimeOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOE] : null;
        var oddsFHalfOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOE] : null;
        var oddsFTimeCS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeCS] : null;
        var oddsFHalfCS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfCS] : null;
        var oddsHTFT = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.HTFT] : null;
        var oddsFGLG = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FGLG] : null;
        var oddsTG = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.TG] : null;
        var oddsML = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.ML] : null;
        var oddsDC = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.DC] : null;
        var homeScore = eventResult[3];
        var awayScore = eventResult[4];
        var i;
        var odds;
        var price;
        var allPrices;
        var allPricesCount;
        var validPricesCount;
        var rowLength;
        var rowIndex;
        var row1Cells;
        var row2Cells;
        var row1;
        var row2;
        var marketPage = $M('odds-display').getDisplaySetting('market-page');
        if (marketPage == 9) {
            _selectedOddId = $M('ticket').getOddsIdDictionary();
        } else {
            _selectedOddId = $M('ticket').getOddIdOption();
        }
        var dd;
        if (oddsFTimeLS && oddsFTimeLS.length > 0) {
            dd = {};
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsFTimeLS[0];
            _populateOdds(dd, odds, _MarketDisplay.FTimeLS);
            blocks.push(1);
            blocks.push(_template['ft-ls-block'].getText(dd));
        }
        if (oddsFHalfLS && oddsFHalfLS.length > 0) {
            dd = {};
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsFHalfLS[0];
            _populateOdds(dd, odds, _MarketDisplay.FHalfLS);
            blocks.push(1);
            blocks.push(_template['fh-ls-block'].getText(dd));
        }
        if (oddsML && oddsML.length > 0) {
            dd = {};
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsML[0];
            _populateOdds(dd, odds, _MarketDisplay.ML);
            blocks.push(1);
            blocks.push(_template['ml-block'].getText(dd));
        }
        var hdpouRowCount = 0;
        if (oddsFTimeHDP && hdpouRowCount < oddsFTimeHDP.length) {
            hdpouRowCount = oddsFTimeHDP.length;
        }
        if (oddsFHalfHDP && hdpouRowCount < oddsFHalfHDP.length) {
            hdpouRowCount = oddsFHalfHDP.length;
        }
        if (oddsFTimeOU && hdpouRowCount < oddsFTimeOU.length) {
            hdpouRowCount = oddsFTimeOU.length;
        }
        if (oddsFHalfOU && hdpouRowCount < oddsFHalfOU.length) {
            hdpouRowCount = oddsFHalfOU.length;
        }
        if (hdpouRowCount > 0) {
            var hdpouRows = [];
            for (var hdpouRowIndex = 0; hdpouRowIndex < hdpouRowCount; ++hdpouRowIndex) {
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[hdpouRowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[hdpouRowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['h-color-class'] = hdp > 0 ? 'Red' : 'Blue';
                d['a-color-class'] = hdp < 0 ? 'Red' : 'Blue';
                odds = oddsFTimeHDP ? oddsFTimeHDP[hdpouRowIndex] : null;
                _populateOdds(d, odds, _MarketDisplay.FTimeHDP);
                odds = oddsFHalfHDP ? oddsFHalfHDP[hdpouRowIndex] : null;
                _populateOdds(d, odds, _MarketDisplay.FHalfHDP);
                odds = oddsFTimeOU ? oddsFTimeOU[hdpouRowIndex] : null;
                _populateOdds(d, odds, _MarketDisplay.FTimeOU);
                odds = oddsFHalfOU ? oddsFHalfOU[hdpouRowIndex] : null;
                _populateOdds(d, odds, _MarketDisplay.FHalfOU);
                hdpouRows.push(_template['hdp-ou-row'].getText(d));
            }
            d['hdp-ou-rows'] = hdpouRows.join('');
            blocks.push(3);
            blocks.push(_template['box-hdp-ou'].getText(d));
        }
        if (oddsFTime1X2 && oddsFTime1X2.length > 0) {
            dd = {};
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsFTime1X2[0];
            _populateOdds(dd, odds, _MarketDisplay.FTime1X2);
            blocks.push(1);
            blocks.push(_template['ft-1x2-block'].getText(dd));
        }
        if (oddsFHalf1X2 && oddsFHalf1X2.length > 0) {
            dd = {};
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsFHalf1X2[0];
            _populateOdds(dd, odds, _MarketDisplay.FHalf1X2);
            blocks.push(1);
            blocks.push(_template['fh-1x2-block'].getText(dd));
        }
        if (oddsFTimeOE && oddsFTimeOE.length > 0) {
            dd = {};
            odds = oddsFTimeOE[0];
            dd['home'] = _template['resource-odd'].getText(dd);
            dd['away'] = _template['resource-even'].getText(dd);
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            _populateOdds(dd, odds, _MarketDisplay.FTimeOE);
            blocks.push(1);
            blocks.push(_template['ft-oe-block'].getText(dd));
        }
        if (oddsFHalfOE && oddsFHalfOE.length > 0) {
            dd = {};
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsFHalfOE[0];
            dd['home'] = _template['resource-odd'].getText(dd);
            dd['away'] = _template['resource-even'].getText(dd);
            _populateOdds(dd, odds, _MarketDisplay.FHalfOE);
            blocks.push(1);
            blocks.push(_template['fh-oe-block'].getText(dd));
        }
        if (oddsTG && oddsTG.length > 0) {
            dd = {};
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsTG[0];
            if (_cache.isLive()) {
                _populateOdds(dd, odds, _MarketDisplay.TG);
                allPrices = odds[2];
                allPricesCount = allPrices.length;
                validPricesCount = 0;
                var lastCol = -1;
                for (i = 0; i < allPricesCount; i++) {
                    price = allPrices[i];
                    if (price && price > 1) {
                        if (lastCol >= 0) {
                            dd['tg-' + lastCol + '-more-last-col'] = '';
                        }
                        lastCol = i;
                        dd['tg-' + lastCol + '-more-last-col'] = 'more-last-col';
                        validPricesCount++;
                    } else {
                        dd['tg-' + i + '-td-class'] = 'hide';
                    }
                }
                dd['column-number'] = validPricesCount;
                blocks.push(1);
                blocks.push(_template['live-tg-block'].getText(dd));
            } else {
                dd = {};
                dd['price-or-mpprice'] = d['price-or-mpprice'];
                _populateOdds(dd, odds, _MarketDisplay.TG);
                blocks.push(1);
                blocks.push(_template['nonlive-tg-block'].getText(dd));
            }
        }
        if (oddsDC && oddsDC.length > 0) {
            dd = {};
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsDC[0];
            _populateOdds(dd, odds, _MarketDisplay.DC);
            blocks.push(1);
            blocks.push(_template['dc-block'].getText(dd));
        }
        if (oddsFTimeCS && oddsFTimeCS.length > 0) {
            odds = oddsFTimeCS[0];
            if (_cache.isLive()) {
                allPrices = odds[2];
                allPricesCount = allPrices.length;
                priceIndicator = _cache.getPriceAdjustIndicators(odds[0]);
                validPricesCount = 0;
                for (i = 0; i < allPricesCount; i++) {
                    price = allPrices[i];
                    if (price && price > 1) {
                        validPricesCount++;
                    }
                }
                rowLength = (validPricesCount >= 14) ? parseInt((validPricesCount + 1) / 2) : validPricesCount;
                i = 0;
                rowIndex = 0;
                row1Cells = [];
                while (i < allPricesCount && rowIndex < rowLength) {
                    dd = {};
                    dd['price-or-mpprice'] = d['price-or-mpprice'];
                    price = allPrices[i];
                    if (price && price > 1) {
                        dd['black-or-red'] = 'black';
                        if (i == allPricesCount - 1) {
                            dd['cell-title'] = _template['title-cs-other'].getText(d);
                            dd['cell-title-tooltip'] = _template['tooltip-aos'].getText();
                        } else {
                            dd['home-score'] = (homeScore + parseInt(i / 5)).toFixed(0);
                            dd['away-score'] = (awayScore + (i % 5)).toFixed(0);
                            dd['cell-title'] = _template['score'].getText(dd);
                            dd['cell-title-tooltip'] = _template['tooltip-cs'].getText() + dd['home-score'] + ':' + dd['away-score'];
                        }
                        dd['cell-price'] = OddsUtility.getPriceText(dd, odds, _template['price-text'], i);
                        dd['cell-indicator'] = '';
                        if (priceIndicator[i]) {
                            if (priceIndicator[i] != -2) {
                                dd['cell-indicator'] = priceIndicator[i] > 0 ? 'price-up' : 'price-down';
                            }
                            dd['cell-class'] = 'odds-change';
                        }
                        if (_selectedOddId == dd['odds-id'] + dd['odds-option']) {
                            dd['cell-indicator'] += ' odds-selected';
                        } else {
                            dd['cell-indicator'] += ' dummy-more-class';
                        }
                        if (rowIndex == rowLength - 1) {
                            dd['more-last-col'] = 'more-last-col';
                        } else {
                            dd['more-last-col'] = '';
                        }
                        row1Cells.push(_template['normal-cell'].getText(dd));
                        rowIndex++;
                    }
                    i++;
                }
                if (row1Cells.length > 0) {
                    row1 = _template['live-cs-row'].getText({
                        'cells': row1Cells.join('')
                    });
                } else {
                    row1 = '';
                }
                rowIndex = 0;
                row2Cells = [];
                while (i < allPricesCount) {
                    dd = {};
                    dd['price-or-mpprice'] = d['price-or-mpprice'];
                    price = allPrices[i];
                    if (price && price > 1) {
                        dd['black-or-red'] = 'black';
                        if (i == allPricesCount - 1) {
                            dd['cell-title'] = _template['title-cs-other'].getText(d);
                            dd['cell-title-tooltip'] = _template['tooltip-aos'].getText();
                        } else {
                            dd['home-score'] = (homeScore + parseInt(i / 5)).toFixed(0);
                            dd['away-score'] = (awayScore + (i % 5)).toFixed(0);
                            dd['cell-title'] = _template['score'].getText(dd);
                            dd['cell-title-tooltip'] = _template['tooltip-cs'].getText() + dd['home-score'] + ':' + dd['away-score'];
                        }
                        dd['cell-price'] = OddsUtility.getPriceText(dd, odds, _template['price-text'], i);
                        dd['cell-indicator'] = '';
                        if (priceIndicator[i]) {
                            if (priceIndicator[i] != -2) {
                                dd['cell-indicator'] = priceIndicator[i] > 0 ? 'price-up' : 'price-down';
                            }
                            dd['cell-class'] = 'odds-change';
                        }
                        if (_selectedOddId == dd['odds-id'] + dd['odds-option']) {
                            dd['cell-indicator'] += ' odds-selected';
                        } else {
                            dd['cell-indicator'] += ' dummy-more-class';
                        }
                        if (rowIndex == rowLength - 1) {
                            dd['more-last-col'] = 'more-last-col';
                        } else {
                            dd['more-last-col'] = '';
                        }
                        row2Cells.push(_template['normal-cell'].getText(dd));
                        rowIndex++;
                    }
                    i++;
                }
                if (validPricesCount > 14 && rowIndex < rowLength) {
                    dd = {};
                    dd['black-or-red'] = 'black';
                    row2Cells.push(_template['empty-cell'].getText(dd));
                }
                if (row2Cells.length > 0) {
                    row2 = _template['live-cs-row'].getText({
                        'cells': row2Cells.join('')
                    });
                } else {
                    row2 = '';
                }
                if (row1 != '') {
                    var widthWeight = (rowLength >= 7) ? 3 : (rowLength >= 6 ? 2 : (rowLength >= 5 ? 1.5 : 1));
                    blocks.push(widthWeight);
                    blocks.push(_template['live-cs-block'].getText({
                        'rows': (row1 + row2),
                        'column-number': rowLength
                    }));
                }
            } else {
                dd = {};
                dd['price-or-mpprice'] = d['price-or-mpprice'];
                _populateOdds(dd, odds, _MarketDisplay.FTimeCS);
                blocks.push(3);
                blocks.push(_template['nonlive-cs-block'].getText(dd));
            }
        }
        if (oddsFHalfCS && oddsFHalfCS.length > 0) {
            odds = oddsFHalfCS[0];
            if (_cache.isLive()) {
                allPrices = odds[2];
                allPricesCount = allPrices.length;
                priceIndicator = _cache.getPriceAdjustIndicators(odds[0]);
                validPricesCount = 0;
                for (i = 0; i < allPricesCount; i++) {
                    price = allPrices[i];
                    if (price && price > 1) {
                        validPricesCount++;
                    }
                }
                rowLength = (validPricesCount >= 14) ? parseInt((validPricesCount + 1) / 2) : validPricesCount;
                i = 0;
                rowIndex = 0;
                row1Cells = [];
                while (i < allPricesCount && rowIndex < rowLength) {
                    dd = {};
                    dd['price-or-mpprice'] = d['price-or-mpprice'];
                    price = allPrices[i];
                    if (price && price > 1) {
                        dd['black-or-red'] = 'black';
                        if (i == allPricesCount - 1) {
                            dd['cell-title'] = _template['title-cs-other'].getText(d);
                            dd['cell-title-tooltip'] = _template['tooltip-aos'].getText();
                        } else {
                            dd['home-score'] = (homeScore + parseInt(i / 4)).toFixed(0);
                            dd['away-score'] = (awayScore + (i % 4)).toFixed(0);
                            dd['cell-title'] = _template['score'].getText(dd);
                            dd['cell-title-tooltip'] = _template['tooltip-fhcs'].getText() + dd['home-score'] + ':' + dd['away-score'];
                        }
                        dd['cell-price'] = OddsUtility.getPriceText(dd, odds, _template['price-text'], i);
                        dd['cell-indicator'] = '';
                        if (priceIndicator[i]) {
                            if (priceIndicator[i] != -2) {
                                dd['cell-indicator'] = priceIndicator[i] > 0 ? 'price-up' : 'price-down';
                            }
                            dd['cell-class'] = 'odds-change';
                        }
                        if (_selectedOddId == dd['odds-id'] + dd['odds-option']) {
                            dd['cell-indicator'] += ' odds-selected';
                        } else {
                            dd['cell-indicator'] += ' dummy-more-class';
                        }
                        if (rowIndex == rowLength - 1) {
                            dd['more-last-col'] = 'more-last-col';
                        } else {
                            dd['more-last-col'] = '';
                        }
                        row1Cells.push(_template['normal-cell'].getText(dd));
                        rowIndex++;
                    }
                    i++;
                }
                if (row1Cells.length > 0) {
                    row1 = _template['live-cs-row'].getText({
                        'cells': row1Cells.join('')
                    });
                } else {
                    row1 = '';
                }
                rowIndex = 0;
                row2Cells = [];
                while (i < allPricesCount) {
                    dd = {};
                    dd['price-or-mpprice'] = d['price-or-mpprice'];
                    price = allPrices[i];
                    if (price && price > 1) {
                        dd['black-or-red'] = 'black';
                        if (i == allPricesCount - 1) {
                            dd['cell-title'] = _template['title-cs-other'].getText(d);
                            dd['cell-title-tooltip'] = _template['tooltip-aos'].getText();
                        } else {
                            dd['home-score'] = (homeScore + parseInt(i / 4)).toFixed(0);
                            dd['away-score'] = (awayScore + (i % 4)).toFixed(0);
                            dd['cell-title'] = _template['score'].getText(dd);
                            dd['cell-title-tooltip'] = _template['tooltip-fhcs'].getText() + dd['home-score'] + ':' + dd['away-score'];
                        }
                        dd['cell-price'] = OddsUtility.getPriceText(dd, odds, _template['price-text'], i);
                        dd['cell-indicator'] = '';
                        if (priceIndicator[i]) {
                            if (priceIndicator[i] != -2) {
                                dd['cell-indicator'] = priceIndicator[i] > 0 ? 'price-up' : 'price-down';
                            }
                            dd['cell-class'] = 'odds-change';
                        }
                        if (_selectedOddId == dd['odds-id'] + dd['odds-option']) {
                            dd['cell-indicator'] += ' odds-selected';
                        } else {
                            dd['cell-indicator'] += ' dummy-more-class';
                        }
                        if (rowIndex == rowLength - 1) {
                            dd['more-last-col'] = 'more-last-col';
                        } else {
                            dd['more-last-col'] = '';
                        }
                        row2Cells.push(_template['normal-cell'].getText(dd));
                        rowIndex++;
                    }
                    i++;
                }
                if (validPricesCount > 14 && rowIndex < rowLength) {
                    dd = {};
                    dd['black-or-red'] = 'black';
                    row2Cells.push(_template['empty-cell'].getText(dd));
                }
                if (row2Cells.length > 0) {
                    row2 = _template['live-cs-row'].getText({
                        'cells': row2Cells.join('')
                    });
                } else {
                    row2 = '';
                }
                if (row1 != '') {
                    var widthWeight = (rowLength >= 7) ? 3 : (rowLength >= 6 ? 2 : (rowLength >= 5 ? 1.5 : 1));
                    blocks.push(widthWeight);
                    blocks.push(_template['live-fh-cs-block'].getText({
                        'rows': (row1 + row2),
                        'column-number': rowLength
                    }));
                }
            } else {
                dd = {};
                dd['price-or-mpprice'] = d['price-or-mpprice'];
                _populateOdds(dd, odds, _MarketDisplay.FHalfCS);
                blocks.push(3);
                blocks.push(_template['nonlive-fh-cs-block'].getText(dd));
            }
        }
        if (oddsHTFT && oddsHTFT.length > 0) {
            dd = {};
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsHTFT[0];
            _populateOdds(dd, odds, _MarketDisplay.HTFT);
            blocks.push(3);
            blocks.push(_template['htft-block'].getText(dd));
        }
        if (oddsFGLG && oddsFGLG.length > 0) {
            dd = {};
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsFGLG[0];
            _populateOdds(dd, odds, _MarketDisplay.FGLG);
            blocks.push(1.5);
            blocks.push(_template['fglg-block'].getText(dd));
        }
    }

    function _populateSpecialDoubleMarkets(boxes, d, tagEventResult) {
        var eventResult = tagEventResult[2];
        var eventResultId = eventResult[0];
        var oddsByMarketDisplayId = tagEventResult[3];
        var marketGroup = tagEventResult[4];
        var oddsFTime1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTime1X2] : null;
        var oddsFHalf1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalf1X2] : null;
        var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
        var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
        var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
        var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
        var oddsFTimeOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOE] : null;
        var oddsFHalfOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOE] : null;
        var oddsML = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.ML] : null;
        d['event-result-id'] = eventResultId;
        var liveScore = '';
        if (eventResult) {
            var homescore = eventResult[3];
            var awayscore = eventResult[4];
            if (_cache.isLive()) {
                liveScore = _template['live-score'].getText({
                    'homescore': homescore,
                    'awayscore': awayscore
                });
            }
        }
        var rowCount = 0;
        if (oddsFTime1X2 && rowCount < oddsFTime1X2.length) {
            rowCount = oddsFTime1X2.length;
        }
        if (oddsFHalf1X2 && rowCount < oddsFHalf1X2.length) {
            rowCount = oddsFHalf1X2.length;
        }
        if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
            rowCount = oddsFTimeHDP.length;
        }
        if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
            rowCount = oddsFHalfHDP.length;
        }
        if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
            rowCount = oddsFTimeOU.length;
        }
        if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
            rowCount = oddsFHalfOU.length;
        }
        if (oddsFTimeOE && rowCount < oddsFTimeOE.length) {
            rowCount = oddsFTimeOE.length;
        }
        if (oddsFHalfOE && rowCount < oddsFHalfOE.length) {
            rowCount = oddsFHalfOE.length;
        }
        if (oddsML && rowCount < oddsML.length) {
            rowCount = oddsML.length;
        }
        if (rowCount <= 0) {
            return;
        }
        var marketPage = $M('odds-display').getDisplaySetting('market-page');
        if (marketPage == 9) {
            _selectedOddId = $M('ticket').getOddsIdDictionary();
        } else {
            _selectedOddId = $M('ticket').getOddIdOption();
        }
        for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
            var odds;
            var has1X2 = false;
            var hasHDP = false;
            var hasOU = false;
            var hasOE = false;
            var hasML = false;
            var columns = 1;
            var columnWeight = 0;
            var hdp = 0;
            odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
            if (odds) {
                hdp = odds[1][4];
            }
            odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
            if (odds && !hdp) {
                hdp = odds[1][4];
            }
            d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
            d['h-color-class'] = hdp > 0 ? 'Red' : 'Blue';
            d['a-color-class'] = hdp < 0 ? 'Red' : 'Blue';
            odds = oddsFTime1X2 ? oddsFTime1X2[rowIndex] : null;
            if (odds) {
                has1X2 = true;
                columns++;
                _populateOdds(d, odds);
                d['showhide-1x2-style'] = null;
            } else {
                d['showhide-1x2-style'] = 'display:none;';
            }
            odds = oddsFHalf1X2 ? oddsFHalf1X2[rowIndex] : null;
            if (odds) {
                has1X2 = true;
                columns++;
                _populateOdds(d, odds);
                d['showhide-fh1x2-style'] = null;
            } else {
                d['showhide-fh1x2-style'] = 'display:none;';
            }
            odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
            _populateOdds(d, odds, _MarketDisplay.FTimeHDP);
            if (odds) {
                hasHDP = true;
                columns++;
                columnWeight++;
                _populateOdds(d, odds);
                d['showhide-hdp-style'] = null;
            } else {
                d['showhide-hdp-style'] = 'display:none;';
            }
            odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
            _populateOdds(d, odds, _MarketDisplay.FHalfHDP);
            if (odds) {
                hasHDP = true;
                columns++;
                columnWeight++;
                _populateOdds(d, odds);
                d['showhide-fhhdp-style'] = null;
            } else {
                d['showhide-fhhdp-style'] = 'display:none;';
            }
            odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
            if (odds) {
                hasOU = true;
                columns++;
                columnWeight++;
                _populateOdds(d, odds);
                d['showhide-ou-style'] = null;
            } else {
                d['showhide-ou-style'] = 'display:none;';
            }
            odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
            if (odds) {
                hasOU = true;
                columns++;
                columnWeight++;
                _populateOdds(d, odds);
                d['showhide-fhou-style'] = null;
            } else {
                d['showhide-fhou-style'] = 'display:none;';
            }
            odds = oddsFTimeOE ? oddsFTimeOE[rowIndex] : null;
            if (odds) {
                hasOE = true;
                columns++;
                _populateOdds(d, odds);
                d['showhide-oe-style'] = null;
            } else {
                d['showhide-oe-style'] = 'display:none;';
            }
            odds = oddsFHalfOE ? oddsFHalfOE[rowIndex] : null;
            if (odds) {
                hasOE = true;
                columns++;
                _populateOdds(d, odds);
                d['showhide-fhoe-style'] = null;
            } else {
                d['showhide-fhoe-style'] = 'display:none;';
            }
            odds = oddsML ? oddsML[rowIndex] : null;
            if (odds) {
                hasML = true;
                columns++;
                _populateOdds(d, odds);
                d['showhide-ml-style'] = null;
            } else {
                d['showhide-ml-style'] = 'display:none;';
            }
            if (marketGroup[5]) {
                d['h'] = d['home'];
                d['h-tooltip'] = d['home'];
                d['a'] = d['away'];
                d['a-tooltip'] = d['away'];
            } else if (hasOU && !has1X2 && !hasML && !hasHDP && !hasOE) {
                d['h'] = _template['resource-over'].getText();
                d['h-tooltip'] = _template['over-tooltip'].getText();
                d['a'] = _template['resource-under'].getText();
                d['a-tooltip'] = _template['under-tooltip'].getText();
            } else if (hasOE && !has1X2 && !hasML && !hasHDP && !hasOU) {
                d['h'] = _template['resource-odd'].getText();
                d['h-tooltip'] = _template['odd-tooltip'].getText();
                d['a'] = _template['resource-even'].getText();
                d['a-tooltip'] = _template['even-tooltip'].getText();
            } else {
                d['h'] = _template['resource-home'].getText();
                d['h-tooltip'] = _template['home-tooltip'].getText();
                d['a'] = _template['resource-away'].getText();
                d['a-tooltip'] = _template['away-tooltip'].getText();
            }
            d['live-score'] = liveScore;
            d['column-count'] = Math.min(columns, 13);
            columnWeight += columns;
            d['box-double-width'] = (columnWeight >= 9) ? 792 : ((columnWeight >= 6) ? 528 : (columnWeight >= 4 ? 395 : 259));
            var weightWidth = (columnWeight >= 9) ? 3 : ((columnWeight >= 6) ? 2 : (columnWeight >= 4 ? 1.5 : 1));
            boxes.push(weightWidth);
            if (has1X2) {
                boxes.push(_template['box-double'].getText(d));
            } else {
                boxes.push(_template['box-double-no1x2'].getText(d));
            }
        }
    }

    function _populateSpecialMarkets(blocks, d, tagEventResult) {
        var eventResult = tagEventResult[2];
        var eventResultId = eventResult[0];
        var oddsByMarketDisplayId = tagEventResult[3];
        var marketGroup = tagEventResult[4];
        var oddsFTime1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTime1X2] : null;
        var oddsFHalf1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalf1X2] : null;
        var oddsFTimeLS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeLS] : null;
        var oddsFHalfLS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfLS] : null;
        var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
        var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
        var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
        var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
        var oddsFTimeOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOE] : null;
        var oddsFHalfOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOE] : null;
        var oddsML = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.ML] : null;
        var i;
        var odds;
        var dd;
        var liveScore = '';
        var marketPage = $M('odds-display').getDisplaySetting('market-page');
        if (marketPage == 9) {
            _selectedOddId = $M('ticket').getOddsIdDictionary();
        } else {
            _selectedOddId = $M('ticket').getOddIdOption();
        }
        if (eventResult) {
            var homescore = eventResult[3];
            var awayscore = eventResult[4];
            if (_cache.isLive()) {
                liveScore = _template['live-score'].getText({
                    'homescore': homescore,
                    'awayscore': awayscore
                });
            }
        }
        if (oddsFTimeLS && oddsFTimeLS.length > 0) {
            dd = {};
            dd['live-score'] = liveScore;
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsFTimeLS[0];
            OddsUtility.populateMarketGroup(dd, marketGroup);
            dd['dash'] = ' - ';
            _populateOdds(dd, odds, _MarketDisplay.FTimeLS);
            blocks.push(1);
            blocks.push(_template['ft-ls-block'].getText(dd));
        }
        if (oddsFHalfLS && oddsFHalfLS.length > 0) {
            dd = {};
            dd['live-score'] = liveScore;
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsFHalfLS[0];
            OddsUtility.populateMarketGroup(dd, marketGroup);
            dd['dash'] = ' - ';
            _populateOdds(dd, odds, _MarketDisplay.FHalfLS);
            blocks.push(1);
            blocks.push(_template['fh-ls-block'].getText(dd));
        }
        if (oddsML && oddsML.length > 0) {
            dd = {};
            dd['live-score'] = liveScore;
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsML[0];
            OddsUtility.populateMarketGroup(dd, marketGroup);
            dd['dash'] = ' - ';
            _populateOdds(dd, odds, _MarketDisplay.ML);
            blocks.push(1);
            blocks.push(_template['ml-block'].getText(dd));
        }
        if (oddsFTimeHDP && oddsFTimeHDP.length > 0) {
            for (i = 0; i < oddsFTimeHDP.length; i++) {
                dd = {};
                dd['live-score'] = liveScore;
                dd['price-or-mpprice'] = d['price-or-mpprice'];
                odds = oddsFTimeHDP[i];
                OddsUtility.populateMarketGroup(dd, marketGroup);
                dd['dash'] = ' - ';
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[i] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                dd['h-color-class'] = hdp > 0 ? 'red' : 'blue';
                dd['a-color-class'] = hdp < 0 ? 'red' : 'blue';
                if (marketGroup[0]) {
                    dd['home'] = d['home'];
                    dd['away'] = d['away'];
                } else {
                    dd['home'] = d['raw-home'];
                    dd['away'] = d['raw-away'];
                }
                _populateOdds(dd, odds, _MarketDisplay.FTimeHDP);
                blocks.push(1);
                if (marketGroup[5]) {
                    blocks.push(_template['ft-hdp-extonly-block'].getText(dd));
                } else {
                    blocks.push(_template['ft-hdp-block'].getText(dd));
                }
            }
        }
        if (oddsFHalfHDP && oddsFHalfHDP.length > 0) {
            for (i = 0; i < oddsFHalfHDP.length; i++) {
                dd = {};
                dd['live-score'] = liveScore;
                dd['price-or-mpprice'] = d['price-or-mpprice'];
                odds = oddsFHalfHDP[i];
                OddsUtility.populateMarketGroup(dd, marketGroup);
                dd['dash'] = ' - ';
                var hdp = 0;
                odds = oddsFHalfHDP ? oddsFHalfHDP[i] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                dd['h-color-class'] = hdp > 0 ? 'red' : 'blue';
                dd['a-color-class'] = hdp < 0 ? 'red' : 'blue';
                if (marketGroup[0]) {
                    dd['home'] = d['home'];
                    dd['away'] = d['away'];
                } else {
                    dd['home'] = d['raw-home'];
                    dd['away'] = d['raw-away'];
                }
                _populateOdds(dd, odds, _MarketDisplay.FHalfHDP);
                blocks.push(1);
                if (marketGroup[5]) {
                    blocks.push(_template['fh-hdp-extonly-block'].getText(dd));
                } else {
                    blocks.push(_template['fh-hdp-block'].getText(dd));
                }
            }
        }
        if (oddsFTimeOU && oddsFTimeOU.length > 0) {
            for (i = 0; i < oddsFTimeOU.length; i++) {
                dd = {};
                dd['live-score'] = liveScore;
                dd['price-or-mpprice'] = d['price-or-mpprice'];
                odds = oddsFTimeOU[i];
                OddsUtility.populateMarketGroup(dd, marketGroup);
                dd['dash'] = ' - ';
                if (marketGroup[0]) {
                    dd['home'] = d['home'];
                    dd['away'] = d['away'];
                } else {
                    dd['home'] = d['raw-home'];
                    dd['away'] = d['raw-away'];
                }
                _populateOdds(dd, odds, _MarketDisplay.FTimeOU);
                blocks.push(1);
                blocks.push(_template['ft-ou-block'].getText(dd));
            }
        }
        if (oddsFHalfOU && oddsFHalfOU.length > 0) {
            for (i = 0; i < oddsFHalfOU.length; i++) {
                dd = {};
                dd['live-score'] = liveScore;
                dd['price-or-mpprice'] = d['price-or-mpprice'];
                odds = oddsFHalfOU[i];
                OddsUtility.populateMarketGroup(dd, marketGroup);
                dd['dash'] = ' - ';
                if (marketGroup[0]) {
                    dd['home'] = d['home'];
                    dd['away'] = d['away'];
                } else {
                    dd['home'] = d['raw-home'];
                    dd['away'] = d['raw-away'];
                }
                _populateOdds(dd, odds, _MarketDisplay.FHalfOU);
                blocks.push(1);
                blocks.push(_template['fh-ou-block'].getText(dd));
            }
        }
        if (oddsFTime1X2 && oddsFTime1X2.length > 0) {
            dd = {};
            dd['live-score'] = liveScore;
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsFTime1X2[0];
            OddsUtility.populateMarketGroup(dd, marketGroup);
            dd['dash'] = ' - ';
            _populateOdds(dd, odds, _MarketDisplay.FTime1X2);
            blocks.push(1);
            blocks.push(_template['ft-1x2-block'].getText(dd));
        }
        if (oddsFHalf1X2 && oddsFHalf1X2.length > 0) {
            dd = {};
            dd['live-score'] = liveScore;
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsFHalf1X2[0];
            OddsUtility.populateMarketGroup(dd, marketGroup);
            dd['dash'] = ' - ';
            _populateOdds(dd, odds, _MarketDisplay.FHalf1X2);
            blocks.push(1);
            blocks.push(_template['fh-1x2-block'].getText(dd));
        }
        if (oddsFTimeOE && oddsFTimeOE.length > 0) {
            dd = {};
            dd['live-score'] = liveScore;
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsFTimeOE[0];
            OddsUtility.populateMarketGroup(dd, marketGroup);
            dd['dash'] = ' - ';
            if (marketGroup[0]) {
                dd['home'] = d['home'];
                dd['away'] = d['away'];
            } else {
                dd['home'] = d['raw-home'];
                dd['away'] = d['raw-away'];
            }
            _populateOdds(dd, odds, _MarketDisplay.FTimeOE);
            blocks.push(1);
            blocks.push(_template['ft-oe-block'].getText(dd));
        }
        if (oddsFHalfOE && oddsFHalfOE.length > 0) {
            dd = {};
            dd['live-score'] = liveScore;
            dd['price-or-mpprice'] = d['price-or-mpprice'];
            odds = oddsFHalfOE[0];
            OddsUtility.populateMarketGroup(dd, marketGroup);
            dd['dash'] = ' - ';
            if (marketGroup[0]) {
                dd['home'] = d['home'];
                dd['away'] = d['away'];
            } else {
                dd['home'] = d['raw-home'];
                dd['away'] = d['raw-away'];
            }
            _populateOdds(dd, odds, _MarketDisplay.FHalfOE);
            blocks.push(1);
            blocks.push(_template['fh-oe-block'].getText(dd));
        }
    }

    function _populateEvent(d, event) {
        d['event-id'] = event[0];
        d['raw-home'] = event[1];
        d['home'] = TiLib.Text.encodeHTML(event[1]);
        d['original-home'] = d['home'];
        d['raw-away'] = event[2];
        d['away'] = TiLib.Text.encodeHTML(event[2]);
        d['original-away'] = d['away'];
        d['home-color-class'] = event[3] == 1 ? 'red' : 'blue';
        d['away-color-class'] = event[3] == 2 ? 'red' : 'blue';
    };

    function _populateOdds(d, odds, marketDisplayId) {
        if (odds) {
            OddsUtility.populateOdds(d, odds, _template['price-text'], _cache.getPriceAdjustIndicators(odds[0]));
            OddsUtility.populateOddsPoints(d, odds, 'more-hdp-point', 'hide');
            OddsUtility.populateOddsLabels(d, odds);
            OddsUtility.populateOddsIndicators(d, odds, _cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down', _selectedOddId);
        } else {
            OddsUtility.clearOdds(d, marketDisplayId);
            OddsUtility.clearOddsPoints(d, marketDisplayId);
            OddsUtility.clearOddsLabels(d, marketDisplayId);
            OddsUtility.clearOddsIndicators(d, marketDisplayId);
        }
    }
}

function __Module_OETG(refreshRate, sortType) {
    var _MarketDisplay = {
        OddEven: 2,
        TotalGoal: 6
    };
    var _TemplateName = 'odds-display/oetg';
    var _self = this;
    var _template = null;
    var _liveCache = new __Cache_Event(sortType);
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _syn = {
        liveWaitingTemplate: false,
        liveDrawing: false,
        liveRefreshRate: refreshRate[0],
        liveRefreshCount: 0,
        liveCooldownCount: 0,
        liveFailureCount: 0,
        liveVersion: 0,
        nonliveWaitingTemplate: false,
        nonliveDrawing: false,
        nonliveRefreshRate: refreshRate[1],
        nonliveRefreshCount: 0,
        nonliveCooldownCount: 0,
        nonliveFailureCount: 0,
        nonliveVersion: 0,
        nonliveWaitToDraw: false
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        if (_template) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_template) {
                    if (_syn.liveWaitingTemplate || _syn.nonliveWaitingTemplate) {
                        _syn.liveWaitingTemplate = false;
                        _syn.nonliveWaitingTemplate = false;
                        _draw();
                    }
                    if (_syn.liveVersion == 0 && _syn.nonliveVersion == 0 && _liveCache.isEmpty() && _nonliveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
    };
    this.onIdle = function (data) {
        var version = data[0];
        var frameIndex = data[1];
        if (frameIndex == 0) {
            if (_syn.liveVersion < version) {
                _syn.liveVersion = version;
            }
            _liveCache.clearAdjustIndicators();
            _drawLive();
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
            }
            _nonliveCache.clearAdjustIndicators();
            _drawNonlive();
            _syn.nonliveDrawing = false;
        }
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var frameIndex = data[1];
        var clearAll = data[2];
        var frameData = data[3];
        var mediaData = data[4];
        var isChanged = false;
        if (frameIndex == 0) {
            if (_liveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.liveVersion < version) {
                _syn.liveVersion = version;
                if (_liveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (isChanged) {
                _drawLive();
                if (_syn.nonliveWaitToDraw) {
                    _syn.nonliveWaitToDraw = false;
                    _drawNonlive();
                }
            }
            if (!isChanged) {
                _drawLive();
            }
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_nonliveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
                if (_nonliveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (isChanged) {
                if (_syn.liveVersion <= 0 && _nonliveCache.isEmpty()) {
                    _syn.nonliveWaitToDraw = true;
                } else {
                    _drawNonlive();
                }
            }
            if (!isChanged) {
                _drawNonlive();
            }
            _syn.nonliveDrawing = false;
        }
    };

    function _submitLive() {
        var sb = [];
        sb.push('odds-display/oetg-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=0&v=');
        sb.push(_syn.liveVersion);
        return TiLib.Ajax.sendRequest('oetg-live', sb.join(''));
    }

    function _submitNonlive() {
        var sb = [];
        sb.push('odds-display/oetg-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=1&v=');
        sb.push(_syn.nonliveVersion);
        return TiLib.Ajax.sendRequest('oetg-nonlive', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.liveCooldownCount) {
            _syn.liveCooldownCount--;
        } else if (_syn.liveDrawing) {
            if (_syn.liveFailureCount > 3) {
                _syn.liveDrawing = false;
            } else {
                _syn.liveFailureCount++;
            }
        } else if (_syn.liveRefreshCount > 0) {
            _drawRefreshButtons('live');
            _syn.liveRefreshCount--;
        } else {
            _syn.liveRefreshCount = _syn.liveRefreshRate;
            _syn.liveCooldownCount = 2;
            _syn.liveDrawing = true;
            _syn.liveFailureCount = 0;
            _submitLive();
            _drawRefreshButtons('live');
        }
        if (_syn.nonliveCooldownCount) {
            _syn.nonliveCooldownCount--;
        } else if (_syn.nonliveDrawing) {
            if (_syn.nonliveFailureCount > 3) {
                _syn.nonliveDrawing = false;
            } else {
                _syn.nonliveFailureCount++;
            }
        } else if (_syn.nonliveRefreshCount > 0) {
            _drawRefreshButtons('nonlive');
            _syn.nonliveRefreshCount--;
        } else {
            _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
            _syn.nonliveCooldownCount = 2;
            _syn.nonliveDrawing = true;
            _syn.nonliveFailureCount = 0;
            _submitNonlive();
            _drawRefreshButtons('nonlive');
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('live');
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('nonlive');
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('live');
                        }, 200);
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('nonlive');
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.liveVersion = 0;
            _syn.nonliveVersion = 0;
        } else if (_syn.liveDrawing || _syn.nonliveDrawing || _syn.liveCooldownCount || _syn.nonliveCooldownCount) {
            return;
        }
        _syn.liveRefreshCount = _syn.liveRefreshRate;
        _syn.liveCooldownCount = 2;
        _syn.liveDrawing = true;
        _syn.liveFailureCount = 0;
        _submitLive();
        _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
        _syn.nonliveCooldownCount = 2;
        _syn.nonliveDrawing = true;
        _syn.nonliveFailureCount = 0;
        _submitNonlive();
        _drawRefreshButtons();
    };
    this.refreshLive = function (clearAll) {
        if (!_syn.liveCooldownCount) {
            if (_syn.liveDrawing) {
                if (_syn.liveFailureCount > 3) {
                    _syn.liveDrawing = false;
                } else {
                    _syn.liveFailureCount++;
                }
            } else {
                if (clearAll) {
                    _syn.liveVersion = 0;
                }
                _syn.liveRefreshCount = _syn.liveRefreshRate;
                _syn.liveCooldownCount = 2;
                _syn.liveDrawing = true;
                _syn.liveFailureCount = 0;
                _submitLive();
                _drawRefreshButtons('live');
            }
        }
    };
    this.refreshNonlive = function (clearAll) {
        if (!_syn.nonliveCooldownCount) {
            if (_syn.nonliveDrawing) {
                if (_syn.nonliveFailureCount > 3) {
                    _syn.nonliveDrawing = false;
                } else {
                    _syn.nonliveFailureCount++;
                }
            } else {
                if (clearAll) {
                    _syn.nonliveVersion = 0;
                }
                _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
                _syn.nonliveCooldownCount = 2;
                _syn.nonliveDrawing = true;
                _syn.nonliveFailureCount = 0;
                _submitNonlive();
                _drawRefreshButtons('nonlive');
            }
        }
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _liveCache.sort(sortType);
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_template) {
            _syn.liveWaitingTemplate = true;
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        _populateNonliveSection(d);
        var div = document.getElementById('module-odds-display');
        if (div) {
            div.innerHTML = _template['odds-display'].getText(d);
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
    }

    function _drawLive() {
        if (!_template) {
            _syn.liveWaitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        var div = document.getElementById('odds-display-live');
        if (div) {
            div.innerHTML = d['odds-display-live'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _template['odds-display'].getText(d);
            }
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
    }

    function _drawNonlive() {
        if (!_template) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        var d = {};
        _populateNonliveSection(d);
        var div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.innerHTML = d['odds-display-nonlive'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _template['odds-display'].getText(d);
            }
        }
    }

    function _drawLoading() {
        if (_syn.liveVersion == 0 && _syn.nonliveVersion == 0 && _liveCache.isEmpty() && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_template && _template['loading']) {
                    text = _template['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _populateLiveSection(d) {
        $M('odds-display').clearRef();
        var template = _template;
        var cache = _liveCache;
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var marketGroupId = 0;
        var showMarketGroups = $M('odds-display').getDisplaySetting('market-showing') == 2 ? true : false;
        var selectedOddId = $M('ticket').getOddIdOption();
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var marketGroup = tagEventResult[6];
            if (marketGroup && marketGroup[0] != 0 && !showMarketGroups) {
                continue;
            }
            var oddsOddEven = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.OddEven] : null;
            var oddsTotalGoal = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.TotalGoal] : null;
            var rowCount = 0;
            if (oddsOddEven && rowCount < oddsOddEven.length) {
                rowCount = oddsOddEven.length;
            }
            if (oddsTotalGoal && rowCount < oddsTotalGoal.length) {
                rowCount = oddsTotalGoal.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                var frozenOdds = eventResultExtra[8];
                var count = null;
                if (frozenOdds) {
                    count = isNaN(frozenOdds[_MarketDisplay.OddEven]) ? 0 : frozenOdds[_MarketDisplay.OddEven];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.TotalGoal]) ? 0 : frozenOdds[_MarketDisplay.TotalGoal];
                    rowCount = Math.max(rowCount, count);
                    rowCount = rowCount > 1 ? 1 : rowCount;
                }
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                marketGroupId = 0;
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasLiveVideo(eventId) ? template['icon-video'].getText(d) : null;
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['home-score'] = eventResult[3];
            d['away-score'] = eventResult[4];
            d['score-class'] = cache.isScoreChanged(eventResultId) ? 'score-change' : null;
            d['live-time'] = template['time-live'].getText(d);
            if (eventResultExtra) {
                var period = eventResultExtra[2];
                if (period > 0) {
                    if (period == 5) {
                        d['live-time'] = template['time-halftime'].getText(d);
                    } else {
                        d['live-time'] = OddsUtility.getLiveTime(period, cache.getLiveStartTime(eventResultId), eventResultExtra[3], eventResultExtra[4]);
                        var injuryTime = parseInt('' + eventResultExtra[7], 10);
                        if (injuryTime && injuryTime > 0) {
                            d['injuryTimeCount'] = injuryTime;
                            d['live-time'] += template['injury-time'].getText(d);
                        }
                    }
                }
            }
            var homeRedCards = '';
            var awayRedCards = '';
            if (eventResultExtra) {
                var redCardIndex;
                var redCardCount = eventResultExtra[5];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        homeRedCards += template['red-card'].getText(d);
                    }
                }
                redCardCount = eventResultExtra[6];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        awayRedCards += template['red-card'].getText(d);
                    }
                }
            }
            d['home-red-cards'] = homeRedCards;
            d['away-red-cards'] = awayRedCards;
            if (marketGroup && marketGroup[0]) {
                OddsUtility.populateMarketGroup(d, marketGroup);
                OddsUtility.populateMarketGroupTeams(d, marketGroup);
                if (marketGroupId != marketGroup[0]) {
                    marketGroupId = marketGroup[0];
                    rows.push(template['row-market-group'].getText(d));
                }
                d['icon-statistics'] = '';
                d['icon-video'] = '';
            } else {
                marketGroupId = 0;
            }
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds = oddsOddEven ? oddsOddEven[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.OddEven);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.OddEven);
                }
                odds = oddsTotalGoal ? oddsTotalGoal[rowIndex] : null;
                if (oddsTotalGoal && oddsTotalGoal[rowIndex]) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.TotalGoal);
                    OddsUtility.clearOdds(d, _MarketDisplay.TotalGoal);
                }
                d['row-index'] = oddsRowIndex++;
                d['bg-color'] = (templateRowIndex & 1) ? '#FFDDCC' : '#FFDDCC';
                rows.push(template['row-event-live'].getText(d));
            }
            templateRowIndex++;
        }
        var ret = 0;
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['refresh-count'] = _syn.liveRefreshCount;
            d['refresh-button'] = _syn.liveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-live'] = template['odds-display-live'].getText(d);
            ret = rows.length;
        } else if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
            _drawLoading();
            ret = 0;
        } else {
            d['odds-display-live'] = '';
            ret = 0;
        }
        return ret;
    }

    function _populateNonliveSection(d) {
        $M('odds-display').clearRef();
        var template = _template;
        var cache = _nonliveCache;
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var selectedOddId = $M('ticket').getOddIdOption();
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var oddsByMarketDisplayId = tagEventResult[5];
            var oddsOddEven = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.OddEven] : null;
            var oddsTotalGoal = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.TotalGoal] : null;
            var rowCount = 0;
            if (oddsOddEven && rowCount < oddsOddEven.length) {
                rowCount = oddsOddEven.length;
            }
            if (oddsTotalGoal && rowCount < oddsTotalGoal.length) {
                rowCount = oddsTotalGoal.length;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                rows.push(template['row-tournament-nonlive'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? template['icon-video-nonlive'].getText(d) : '';
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = template['showtime-date-time'].getText(d);
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds = oddsOddEven ? oddsOddEven[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.OddEven);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.OddEven);
                }
                odds = oddsTotalGoal ? oddsTotalGoal[rowIndex] : null;
                if (oddsTotalGoal && oddsTotalGoal[rowIndex]) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.TotalGoal);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.TotalGoal);
                }
                d['row-index'] = oddsRowIndex++;
                rows.push(template[(templateRowIndex & 1) ? 'row-event-alt' : 'row-event'].getText(d));
            }
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.nonliveRefreshCount;
        d['refresh-button'] = _syn.nonliveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        } else if (cache.isEmpty() && _syn.nonliveVersion == 0) {
            _drawLoading();
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        }
    }

    function _drawRefreshButtons(section) {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        if (section === undefined || section == 'live') {
            var a = document.getElementById('bu:od:refresh-live:button');
            if (a) {
                if (_syn.liveCooldownCount) {
                    a.innerHTML = _template['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _template['refresh'].getText();
                } else {
                    a.innerHTML = _template['refresh-countdown'].getText({
                        'refresh-count': _syn.liveRefreshCount
                    });
                }
            }
        }
        if (section === undefined || section == 'nonlive') {
            a = document.getElementById('bu:od:refresh-nonlive:button');
            if (a) {
                if (_syn.nonliveCooldownCount) {
                    a.innerHTML = _template['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _template['refresh'].getText();
                } else {
                    a.innerHTML = _template['refresh-countdown'].getText({
                        'refresh-count': _syn.nonliveRefreshCount
                    });
                }
            }
        }
    }
}

function __Module_HTFT(refreshRate, sortType) {
    var _MarketDisplay = {
        HTFT: 10
    };
    var _TemplateName = 'odds-display/htft';
    var _self = this;
    var _template = null;
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _selectedOddId = null;
    var _syn = {
        waitingTemplate: false,
        drawing: false,
        refreshRate: refreshRate,
        refreshCount: 0,
        cooldownCount: 0,
        failureCount: 0,
        version: 0
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        if (_template) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_template) {
                    if (_syn.waitingTemplate) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                    if (_syn.liveVersion == 0 && _nonliveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
    };
    this.onIdle = function (version) {
        if (_syn.version < version) {
            _syn.version = version;
        }
        if (_nonliveCache.clearAdjustIndicators()) {
            _draw();
        }
        _syn.drawing = false;
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var clearAll = data[1];
        var nonliveData = data[2];
        var mediaData = data[3];
        var isChanged = false;
        if (clearAll || _syn.version < version) {
            _syn.version = version;
            _nonliveCache.update(clearAll, nonliveData);
            isChanged = true;
        }
        if (_mediaCache.update(mediaData)) {
            isChanged = true;
        }
        if (isChanged) {
            _draw();
        }
        _syn.drawing = false;
    };

    function _submit() {
        var sb = [];
        sb.push('odds-display/htft-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&v=');
        sb.push(_syn.version);
        return TiLib.Ajax.sendRequest('htft', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.cooldownCount) {
            _syn.cooldownCount--;
        } else {
            if (_syn.drawing) {
                if (_syn.failureCount > 3) {
                    _syn.drawing = false;
                } else {
                    _syn.failureCount++;
                }
            } else if (_syn.refreshCount > 0) {
                _drawRefreshButtons();
                _syn.refreshCount--;
            } else {
                _syn.refreshCount = _syn.refreshRate;
                _syn.cooldownCount = 2;
                _syn.drawing = true;
                _syn.failureCount = 0;
                _submit();
                _drawRefreshButtons();
            }
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons();
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons();
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.refresh = function (clearAll) {
        _self.refreshNonlive(clearAll);
    };
    this.refreshNonlive = function (clearAll) {
        if (clearAll) {
            _syn.version = 0;
        } else if (_syn.drawing || _syn.cooldownCount) {
            return;
        }
        _syn.refreshCount = _syn.refreshRate;
        _syn.cooldownCount = 2;
        _syn.drawing = true;
        _syn.failureCount = 0;
        _submit();
        _drawRefreshButtons();
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var nonliveSection = _getNonliveSection();
        var div = document.getElementById('module-odds-display');
        if (div && nonliveSection) {
            div.innerHTML = nonliveSection;
        }
    }

    function _drawLoading() {
        if (_syn.version == 0 && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_template && _template['loading']) {
                    text = _template['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _getNonliveSection() {
        $M('odds-display').clearRef();
        var template = _template;
        var cache = _nonliveCache;
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var d = {};
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        _selectedOddId = $M('ticket').getOddIdOption();
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var oddsByMarketDisplayId = tagEventResult[5];
            var odds = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.HTFT] : null;
            var rowCount = 0;
            if (odds && rowCount < odds.length) {
                rowCount = odds.length;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? template['icon-video-nonlive'].getText(d) : '';
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = template['showtime-date-time'].getText(d);
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odd = odds ? odds[rowIndex] : null;
                _populateOdds(d, odd, cache, template, _MarketDisplay.HTFT);
                d['row-index'] = oddsRowIndex++;
                rows.push(template[(templateRowIndex & 1) ? 'row-event-alt' : 'row-event'].getText(d));
            }
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.refreshCount;
        d['refresh-button'] = _syn.cooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            return template['block-nonlive'].getText(d);
        } else if (_syn.version == 0 && _nonliveCache.isEmpty()) {
            _drawLoading();
            return;
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            return template['block-nonlive'].getText(d);
        }
    }

    function _drawRefreshButtons() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        a = document.getElementById('bu:od:refresh:button');
        if (a) {
            if (_syn.cooldownCount) {
                a.innerHTML = _template['refresh-refreshing'].getText();
            } else if (a.isHover) {
                a.innerHTML = _template['refresh'].getText();
            } else {
                a.innerHTML = _template['refresh-countdown'].getText({
                    'refresh-count': _syn.refreshCount
                });
            }
        }
    }

    function _populateOdds(d, odds, cache, template, marketDisplayId) {
        if (odds) {
            OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, _selectedOddId);
            OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
        } else {
            OddsUtility.clearOdds(d, marketDisplayId);
            OddsUtility.clearOddsIndicators(d, marketDisplayId);
        }
    }
}

function __Module_FGLG(refreshRate, sortType) {
    var _MarketDisplay = {
        FGLG: 13
    };
    var _TemplateName = 'odds-display/fglg';
    var _self = this;
    var _template = null;
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _selectedOddId = null;
    var _syn = {
        waitingTemplate: false,
        drawing: false,
        refreshRate: refreshRate,
        refreshCount: 0,
        cooldownCount: 0,
        failureCount: 0,
        version: 0
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        if (_template) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_template) {
                    if (_syn.waitingTemplate) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                    if (_syn.liveVersion == 0 && _nonliveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
    };
    this.onIdle = function (version) {
        if (_syn.version < version) {
            _syn.version = version;
        }
        if (_nonliveCache.clearAdjustIndicators()) {
            _draw();
        }
        _syn.drawing = false;
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var clearAll = data[1];
        var nonliveData = data[2];
        var mediaData = data[3];
        var isChanged = false;
        if (clearAll || _syn.version < version) {
            _syn.version = version;
            _nonliveCache.update(clearAll, nonliveData);
            isChanged = true;
        }
        if (_mediaCache.update(mediaData)) {
            isChanged = true;
        }
        if (isChanged) {
            _draw();
        }
        _syn.drawing = false;
    };

    function _submit() {
        var sb = [];
        sb.push('odds-display/fglg-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&v=');
        sb.push(_syn.version);
        return TiLib.Ajax.sendRequest('fglg', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.cooldownCount) {
            _syn.cooldownCount--;
        } else {
            if (_syn.drawing) {
                if (_syn.failureCount > 3) {
                    _syn.drawing = false;
                } else {
                    _syn.failureCount++;
                }
            } else if (_syn.refreshCount > 0) {
                _drawRefreshButtons();
                _syn.refreshCount--;
            } else {
                _syn.refreshCount = _syn.refreshRate;
                _syn.cooldownCount = 2;
                _syn.drawing = true;
                _syn.failureCount = 0;
                _submit();
                _drawRefreshButtons();
            }
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons();
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons();
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.refresh = function (clearAll) {
        _self.refreshNonlive(clearAll);
    };
    this.refreshNonlive = function (clearAll) {
        if (clearAll) {
            _syn.version = 0;
        } else if (_syn.drawing || _syn.cooldownCount) {
            return;
        }
        _syn.refreshCount = _syn.refreshRate;
        _syn.cooldownCount = 2;
        _syn.drawing = true;
        _syn.failureCount = 0;
        _submit();
        _drawRefreshButtons();
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var nonliveSection = _getNonliveSection();
        var div = document.getElementById('module-odds-display');
        if (div && nonliveSection) {
            div.innerHTML = nonliveSection;
        }
    }

    function _drawLoading() {
        if (_syn.version == 0 && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_template && _template['loading']) {
                    text = _template['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _getNonliveSection() {
        $M('odds-display').clearRef();
        var template = _template;
        var cache = _nonliveCache;
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var d = {};
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        _selectedOddId = $M('ticket').getOddIdOption();
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var oddsByMarketDisplayId = tagEventResult[5];
            var odds = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FGLG] : null;
            var rowCount = 0;
            if (odds && rowCount < odds.length) {
                rowCount = odds.length;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? template['icon-video-nonlive'].getText(d) : '';
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = template['showtime-date-time'].getText(d);
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odd = odds ? odds[rowIndex] : null;
                _populateOdds(d, odd, cache, template, _MarketDisplay.FGLG);
                d['row-index'] = oddsRowIndex++;
                rows.push(template[(templateRowIndex & 1) ? 'row-event-alt' : 'row-event'].getText(d));
            }
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.refreshCount;
        d['refresh-button'] = _syn.cooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            return template['block-nonlive'].getText(d);
        } else if (_syn.version == 0 && _nonliveCache.isEmpty()) {
            _drawLoading();
            return;
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            return template['block-nonlive'].getText(d);
        }
    }

    function _drawRefreshButtons() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        a = document.getElementById('bu:od:refresh:button');
        if (a) {
            if (_syn.cooldownCount) {
                a.innerHTML = _template['refresh-refreshing'].getText();
            } else if (a.isHover) {
                a.innerHTML = _template['refresh'].getText();
            } else {
                a.innerHTML = _template['refresh-countdown'].getText({
                    'refresh-count': _syn.refreshCount
                });
            }
        }
    }

    function _populateOdds(d, odds, cache, template, marketDisplayId) {
        if (odds) {
            OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, _selectedOddId);
            OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
        } else {
            OddsUtility.clearOdds(d, marketDisplayId);
            OddsUtility.clearOddsIndicators(d, marketDisplayId);
        }
    }
}

function __Module_CS_FT(oddsDisplayInitialParams, sortType) {
    var _MarketDisplay = {
        CS_FT: 4
    };
    var _TemplateName = 'odds-display/cs-ft';
    var _self = this;
    var _template = null;
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _maxPayout = oddsDisplayInitialParams.maxPayout;
    var _selectedOddId = null;
    var _syn = {
        waitingTemplate: false,
        drawing: false,
        refreshRate: oddsDisplayInitialParams.refreshRate,
        refreshCount: 0,
        cooldownCount: 0,
        failureCount: 0,
        version: 0
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        if (_template) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_template) {
                    if (_syn.waitingTemplate) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                    if (_syn.liveVersion == 0 && _nonliveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
    };
    this.onIdle = function (version) {
        if (_syn.version < version) {
            _syn.version = version;
        }
        if (_nonliveCache.clearAdjustIndicators()) {
            _draw();
        }
        _syn.drawing = false;
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var clearAll = data[1];
        var nonliveData = data[2];
        var mediaData = data[3];
        var payout = data[4];
        if (payout) {
            _maxPayout = payout;
        }
        var isChanged = false;
        if (clearAll || _syn.version < version) {
            _syn.version = version;
            _nonliveCache.update(clearAll, nonliveData);
            isChanged = true;
        }
        if (_mediaCache.update(mediaData)) {
            isChanged = true;
        }
        if (isChanged) {
            _draw();
        }
        _syn.drawing = false;
    };

    function _submit() {
        var sb = [];
        sb.push('odds-display/cs-ft-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&v=');
        sb.push(_syn.version);
        return TiLib.Ajax.sendRequest('cs-ft', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.cooldownCount) {
            _syn.cooldownCount--;
        } else {
            if (_syn.drawing) {
                if (_syn.failureCount > 3) {
                    _syn.drawing = false;
                } else {
                    _syn.failureCount++;
                }
            } else if (_syn.refreshCount > 0) {
                _drawRefreshButtons();
                _syn.refreshCount--;
            } else {
                _syn.refreshCount = _syn.refreshRate;
                _syn.cooldownCount = 2;
                _syn.drawing = true;
                _syn.failureCount = 0;
                _submit();
                _drawRefreshButtons();
            }
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons();
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons();
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.refresh = function (clearAll) {
        _self.refreshNonlive(clearAll);
    };
    this.refreshNonlive = function (clearAll) {
        if (clearAll) {
            _syn.version = 0;
        } else if (_syn.drawing || _syn.cooldownCount) {
            return;
        }
        _syn.refreshCount = _syn.refreshRate;
        _syn.cooldownCount = 2;
        _syn.drawing = true;
        _syn.failureCount = 0;
        _submit();
        _drawRefreshButtons();
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var nonliveSection = _getNonliveSection();
        var div = document.getElementById('module-odds-display');
        if (div && nonliveSection) {
            div.innerHTML = nonliveSection;
        }
    }

    function _drawLoading() {
        if (_syn.version == 0 && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_template && _template['loading']) {
                    text = _template['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _getNonliveSection() {
        $M('odds-display').clearRef();
        var template = _template;
        var cache = _nonliveCache;
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var d = {};
        var lang = TiLib.GlobalCache.getItem('lang');
        d['max-payout'] = _template['max-payout'].getText({
            'max-payout-amount': _maxPayout
        });
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        d['cs-max-payout-extra-css'] = (lang && lang == 'vi-vn') ? 'cs-fh-max-payout-vi-vn' : '';
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        _selectedOddId = $M('ticket').getOddIdOption();
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var oddsByMarketDisplayId = tagEventResult[5];
            var odds = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.CS_FT] : null;
            var rowCount = 0;
            if (odds && rowCount < odds.length) {
                rowCount = odds.length;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? template['icon-video-nonlive'].getText(d) : '';
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = template['showtime-date-time'].getText(d);
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odd = odds ? odds[rowIndex] : null;
                _populateOdds(d, odd, cache, template, _MarketDisplay.CS_FT);
                d['row-index'] = oddsRowIndex++;
                rows.push(template[(templateRowIndex & 1) ? 'row-event-alt' : 'row-event'].getText(d));
            }
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.refreshCount;
        d['refresh-button'] = _syn.cooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            return template['block-nonlive'].getText(d);
        } else if (_syn.version == 0 && _nonliveCache.isEmpty()) {
            _drawLoading();
            return;
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            return template['block-nonlive'].getText(d);
        }
    }

    function _drawRefreshButtons() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        a = document.getElementById('bu:od:refresh:button');
        if (a) {
            if (_syn.cooldownCount) {
                a.innerHTML = _template['refresh-refreshing'].getText();
            } else if (a.isHover) {
                a.innerHTML = _template['refresh'].getText();
            } else {
                a.innerHTML = _template['refresh-countdown'].getText({
                    'refresh-count': _syn.refreshCount
                });
            }
        }
    }

    function _populateOdds(d, odds, cache, template, marketDisplayId) {
        if (odds) {
            OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, _selectedOddId);
            OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
        } else {
            OddsUtility.clearOdds(d, marketDisplayId);
            OddsUtility.clearOddsIndicators(d, marketDisplayId);
        }
    }
}

function __Module_CS_FH(oddsDisplayInitialParams, sortType) {
    var _MarketDisplay = {
        CS_FH: 14
    };
    var _TemplateName = 'odds-display/cs-fh';
    var _self = this;
    var _template = null;
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _maxPayout = oddsDisplayInitialParams.maxPayout;
    var _selectedOddId = null;
    var _syn = {
        waitingTemplate: false,
        drawing: false,
        refreshRate: oddsDisplayInitialParams.refreshRate,
        refreshCount: 0,
        cooldownCount: 0,
        failureCount: 0,
        version: 0
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        if (_template) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_template) {
                    if (_syn.waitingTemplate) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                    if (_syn.liveVersion == 0 && _nonliveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
    };
    this.onIdle = function (version) {
        if (_syn.version < version) {
            _syn.version = version;
        }
        if (_nonliveCache.clearAdjustIndicators()) {
            _draw();
        }
        _syn.drawing = false;
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var clearAll = data[1];
        var nonliveData = data[2];
        var mediaData = data[3];
        var payout = data[4];
        if (payout) {
            _maxPayout = payout;
        }
        var isChanged = false;
        if (clearAll || _syn.version < version) {
            _syn.version = version;
            _nonliveCache.update(clearAll, nonliveData);
            isChanged = true;
        }
        if (_mediaCache.update(mediaData)) {
            isChanged = true;
        }
        if (isChanged) {
            _draw();
        }
        _syn.drawing = false;
    };

    function _submit() {
        var sb = [];
        sb.push('odds-display/cs-fh-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&v=');
        sb.push(_syn.version);
        return TiLib.Ajax.sendRequest('cs-fh', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.cooldownCount) {
            _syn.cooldownCount--;
        } else {
            if (_syn.drawing) {
                if (_syn.failureCount > 3) {
                    _syn.drawing = false;
                } else {
                    _syn.failureCount++;
                }
            } else if (_syn.refreshCount > 0) {
                _drawRefreshButtons();
                _syn.refreshCount--;
            } else {
                _syn.refreshCount = _syn.refreshRate;
                _syn.cooldownCount = 2;
                _syn.drawing = true;
                _syn.failureCount = 0;
                _submit();
                _drawRefreshButtons();
            }
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons();
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons();
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.refresh = function (clearAll) {
        _self.refreshNonlive(clearAll);
    };
    this.refreshNonlive = function (clearAll) {
        if (clearAll) {
            _syn.version = 0;
        } else if (_syn.drawing || _syn.cooldownCount) {
            return;
        }
        _syn.refreshCount = _syn.refreshRate;
        _syn.cooldownCount = 2;
        _syn.drawing = true;
        _syn.failureCount = 0;
        _submit();
        _drawRefreshButtons();
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var nonliveSection = _getNonliveSection();
        var div = document.getElementById('module-odds-display');
        if (div && nonliveSection) {
            div.innerHTML = nonliveSection;
        }
    }

    function _drawLoading() {
        if (_syn.version == 0 && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_template && _template['loading']) {
                    text = _template['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _getNonliveSection() {
        $M('odds-display').clearRef();
        var template = _template;
        var cache = _nonliveCache;
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var d = {};
        var lang = TiLib.GlobalCache.getItem('lang');
        d['max-payout'] = _template['max-payout'].getText({
            'max-payout-amount': _maxPayout
        });
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        d['cs-max-payout-extra-css'] = (lang && lang == 'vi-vn') ? 'cs-fh-max-payout-vi-vn' : '';
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        _selectedOddId = $M('ticket').getOddIdOption();
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var oddsByMarketDisplayId = tagEventResult[5];
            var odds = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.CS_FH] : null;
            var rowCount = 0;
            if (odds && rowCount < odds.length) {
                rowCount = odds.length;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? template['icon-video-nonlive'].getText(d) : '';
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = template['showtime-date-time'].getText(d);
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odd = odds ? odds[rowIndex] : null;
                _populateOdds(d, odd, cache, template, _MarketDisplay.CS_FH);
                d['row-index'] = oddsRowIndex++;
                rows.push(template[(templateRowIndex & 1) ? 'row-event-alt' : 'row-event'].getText(d));
            }
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.refreshCount;
        d['refresh-button'] = _syn.cooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            return template['block-nonlive'].getText(d);
        } else if (_syn.version == 0 && _nonliveCache.isEmpty()) {
            _drawLoading();
            return;
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            return template['block-nonlive'].getText(d);
        }
    }

    function _drawRefreshButtons() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        a = document.getElementById('bu:od:refresh:button');
        if (a) {
            if (_syn.cooldownCount) {
                a.innerHTML = _template['refresh-refreshing'].getText();
            } else if (a.isHover) {
                a.innerHTML = _template['refresh'].getText();
            } else {
                a.innerHTML = _template['refresh-countdown'].getText({
                    'refresh-count': _syn.refreshCount
                });
            }
        }
    }

    function _populateOdds(d, odds, cache, template, marketDisplayId) {
        if (odds) {
            OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, _selectedOddId);
            OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
        } else {
            OddsUtility.clearOdds(d, marketDisplayId);
            OddsUtility.clearOddsIndicators(d, marketDisplayId);
        }
    }
}

function __Module_1X2_DC(refreshRate, sortType) {
    var _MarketDisplay = {
        _1X2_FT: 5,
        _1X2_FH: 8,
        DC: 15
    };
    var _TemplateName = 'odds-display/1x2-dc';
    var _self = this;
    var _template = null;
    var _liveCache = new __Cache_Event(sortType);
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _selectedOddId = null;
    var _syn = {
        waitingTemplate: false,
        liveDrawing: false,
        liveRefreshRate: refreshRate[0],
        liveRefreshCount: 0,
        liveCooldownCount: 0,
        liveFailureCount: 0,
        liveVersion: 0,
        nonliveDrawing: false,
        nonliveRefreshRate: refreshRate[1],
        nonliveRefreshCount: 0,
        nonliveCooldownCount: 0,
        nonliveFailureCount: 0,
        nonliveVersion: 0,
        nonliveWaitToDraw: false
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        if (_template) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_template) {
                    if (_syn.waitingTemplate) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                    if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
    };
    this.onIdle = function (data) {
        var version = data[0];
        var frameIndex = data[1];
        if (frameIndex == 0) {
            if (_syn.liveVersion < version) {
                _syn.liveVersion = version;
            }
            _liveCache.clearAdjustIndicators();
            _drawLive();
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
            }
            if (_nonliveCache.clearAdjustIndicators()) {
                _drawNonlive();
            }
            _syn.nonliveDrawing = false;
        }
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var frameIndex = data[1];
        var clearAll = data[2];
        var frameData = data[3];
        var mediaData = data[4];
        var isChanged = false;
        if (frameIndex == 0) {
            if (_liveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.liveVersion < version) {
                _syn.liveVersion = version;
                if (_liveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (isChanged) {
                _drawLive();
                if (_syn.nonliveWaitToDraw) {
                    _syn.nonliveWaitToDraw = false;
                    _drawNonlive();
                }
            }
            if (!isChanged) {
                _drawLive();
            }
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_nonliveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
                if (_nonliveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (isChanged) {
                if (_syn.liveVersion <= 0 && _nonliveCache.isEmpty()) {
                    _syn.nonliveWaitToDraw = true;
                } else {
                    _drawNonlive();
                }
            }
            if (!isChanged) {
                _drawNonlive();
            }
            _syn.nonliveDrawing = false;
        }
    };

    function _submitLive() {
        var sb = [];
        sb.push('odds-display/1x2-dc-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=0&v=');
        sb.push(_syn.liveVersion);
        sb.push($M('more').getMoreParam(true));
        return TiLib.Ajax.sendRequest('1x2-dc-live', sb.join(''));
    }

    function _submitNonlive() {
        var sb = [];
        sb.push('odds-display/1x2-dc-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=1&v=');
        sb.push(_syn.nonliveVersion);
        sb.push($M('more').getMoreParam(false));
        return TiLib.Ajax.sendRequest('1x2-dc-nonlive', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.liveCooldownCount) {
            _syn.liveCooldownCount--;
        } else if (_syn.liveDrawing) {
            if (_syn.liveFailureCount > 3) {
                _syn.liveDrawing = false;
            } else {
                _syn.liveFailureCount++;
            }
        } else if (_syn.liveRefreshCount > 0) {
            _drawRefreshButtons('live');
            _syn.liveRefreshCount--;
        } else {
            _syn.liveRefreshCount = _syn.liveRefreshRate;
            _syn.liveCooldownCount = 2;
            _syn.liveDrawing = true;
            _syn.liveFailureCount = 0;
            _submitLive();
            _drawRefreshButtons('live');
        }
        if (_syn.nonliveCooldownCount) {
            _syn.nonliveCooldownCount--;
        } else if (_syn.nonliveDrawing) {
            if (_syn.nonliveFailureCount > 3) {
                _syn.nonliveDrawing = false;
            } else {
                _syn.nonliveFailureCount++;
            }
        } else if (_syn.nonliveRefreshCount > 0) {
            _drawRefreshButtons('nonlive');
            _syn.nonliveRefreshCount--;
        } else {
            _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
            _syn.nonliveCooldownCount = 2;
            _syn.nonliveDrawing = true;
            _syn.nonliveFailureCount = 0;
            _submitNonlive();
            _drawRefreshButtons('nonlive');
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('live');
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('nonlive');
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('live');
                        }, 200);
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('nonlive');
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.liveVersion = 0;
            _syn.nonliveVersion = 0;
        } else if (_syn.liveDrawing || _syn.nonliveDrawing || _syn.liveCooldownCount || _syn.nonliveCooldownCount) {
            return;
        }
        _syn.liveRefreshCount = _syn.liveRefreshRate;
        _syn.liveCooldownCount = 2;
        _syn.liveDrawing = true;
        _syn.liveFailureCount = 0;
        _submitLive();
        _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
        _syn.nonliveCooldownCount = 2;
        _syn.nonliveDrawing = true;
        _syn.nonliveFailureCount = 0;
        _submitNonlive();
        _drawRefreshButtons();
    };
    this.refreshLive = function (clearAll) {
        if (!_syn.liveCooldownCount) {
            if (_syn.liveDrawing) {
                if (_syn.liveFailureCount > 3) {
                    _syn.liveDrawing = false;
                } else {
                    _syn.liveFailureCount++;
                }
            } else {
                if (clearAll) _syn.liveVersion = 0;
                _syn.liveRefreshCount = _syn.liveRefreshRate;
                _syn.liveCooldownCount = 2;
                _syn.liveDrawing = true;
                _syn.liveFailureCount = 0;
                _submitLive();
                _drawRefreshButtons('live');
            }
        }
    };
    this.refreshNonlive = function (clearAll) {
        if (!_syn.nonliveCooldownCount) {
            if (_syn.nonliveDrawing) {
                if (_syn.nonliveFailureCount > 3) {
                    _syn.nonliveDrawing = false;
                } else {
                    _syn.nonliveFailureCount++;
                }
            } else {
                if (clearAll) _syn.nonliveVersion = 0;
                _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
                _syn.nonliveCooldownCount = 2;
                _syn.nonliveDrawing = true;
                _syn.nonliveFailureCount = 0;
                _submitNonlive();
                _drawRefreshButtons('nonlive');
            }
        }
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _liveCache.sort(sortType);
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        _populateNonliveSection(d);
        var div = document.getElementById('module-odds-display');
        if (div) {
            div.innerHTML = _template['odds-display'].getText(d);
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
    }

    function _drawLive() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        var div = document.getElementById('odds-display-live');
        if (div) {
            div.innerHTML = d['odds-display-live'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _template['odds-display'].getText(d);
            }
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
    }

    function _drawNonlive() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var d = {};
        _populateNonliveSection(d);
        var div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.innerHTML = d['odds-display-nonlive'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _template['odds-display'].getText(d);
            }
        }
    }

    function _drawLoading() {
        if (_syn.liveVersion == 0 && _syn.nonliveVersion == 0 && _liveCache.isEmpty() && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_template && _template['loading']) {
                    text = _template['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _populateLiveSection(d) {
        $M('odds-display').clearRef();
        var template = _template;
        var cache = _liveCache;
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var marketGroupId = 0;
        var lastEventResultId = 0;
        var showMarketGroups = $M('odds-display').getDisplaySetting('market-showing') == 2 ? true : false;
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        _selectedOddId = $M('ticket').getOddIdOption();
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var odds1x2FT = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay._1X2_FT] : null;
            var odds1x2FH = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay._1X2_FH] : null;
            var oddsDC = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.DC] : null;
            var rowCount = 0;
            var marketGroup = tagEventResult[6];
            if (marketGroup && marketGroup[0] != 0 && !showMarketGroups) {
                continue;
            }
            if (odds1x2FT && rowCount < odds1x2FT.length) {
                rowCount = odds1x2FT.length;
            }
            if (odds1x2FH && rowCount < odds1x2FH.length) {
                rowCount = odds1x2FH.length;
            }
            if (oddsDC && rowCount < oddsDC.length) {
                rowCount = oddsDC.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                var frozenOdds = eventResultExtra[8];
                var count = null;
                if (frozenOdds) {
                    count = isNaN(frozenOdds[_MarketDisplay._1X2_FT]) ? 0 : frozenOdds[_MarketDisplay._1X2_FT];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay._1X2_FH]) ? 0 : frozenOdds[_MarketDisplay._1X2_FH];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.DC]) ? 0 : frozenOdds[_MarketDisplay.DC];
                    rowCount = Math.max(rowCount, count);
                    rowCount = rowCount > 1 ? 1 : rowCount;
                }
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            if (_mediaCache.hasLiveCenter(eventId) && (!marketGroup || marketGroup[0] == 0)) {
                d['icon-live-center'] = template['icon-live-center'].getText(d);
            } else {
                d['icon-live-center'] = null;
            }
            d['icon-video'] = _mediaCache.hasLiveVideo(eventId) && (!marketGroup || marketGroup[0] == 0) ? template['icon-video'].getText(d) : null;
            d['ls-class'] = '';
            d['ls-tooltip'] = '';
            d['ls-id'] = 0;
            if (_mediaCache.hasLiveCenter(eventId)) {
                d['ls-class'] = 'ls-time-column';
                d['ls-tooltip'] = template['ls-tooltip'].getText();
                d['ls-id'] = d['event-id'];
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['home-score'] = eventResult[3];
            d['away-score'] = eventResult[4];
            d['vs'] = template['vs'].getText();
            d['score-separator'] = template['score-separator'].getText(d);
            d['score-class'] = cache.isScoreChanged(eventResultId) ? 'score-change' : '';
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            var moreContent = '';
            if ($M('more').isMoreOpened(eventResultId, 0)) {
                moreContent = $M('more').getContent(_template['col-span'].getText({}));
            } else if ($M('more').isClosing(eventResultId, 0)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = showMarketGroups ? cache.getEventResultMoreOddsCount(eventResultId) : cache.getEventMoreOddsCount(eventResultId);
            d['live-or-nonlive'] = 'live';
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            d['live-time'] = template['time-live'].getText(d);
            if (eventResultExtra) {
                var period = eventResultExtra[2];
                if (period > 0) {
                    if (period == 5) {
                        d['live-time'] = template['time-halftime'].getText(d);
                    } else {
                        d['live-time'] = OddsUtility.getLiveTime(period, cache.getLiveStartTime(eventResultId), eventResultExtra[3], eventResultExtra[4]);
                        var injuryTime = parseInt('' + eventResultExtra[7], 10);
                        if (injuryTime && injuryTime > 0) {
                            d['injuryTimeCount'] = injuryTime;
                            d['live-time'] += template['injury-time'].getText(d);
                        }
                    }
                }
            }
            var homeRedCards = '';
            var awayRedCards = '';
            if (eventResultExtra) {
                var redCardIndex;
                var redCardCount = eventResultExtra[5];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        homeRedCards += template['red-card'].getText(d);
                    }
                }
                redCardCount = eventResultExtra[6];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        awayRedCards += template['red-card'].getText(d);
                    }
                }
            }
            d['home-red-cards'] = homeRedCards;
            d['away-red-cards'] = awayRedCards;
            if (marketGroup && marketGroup[0]) {
                OddsUtility.populateMarketGroup(d, marketGroup);
                OddsUtility.populateMarketGroupTeams(d, marketGroup);
                if (marketGroupId != marketGroup[0]) {
                    marketGroupId = marketGroup[0];
                    rows.push(template['row-market-group'].getText(d));
                }
                d['icon-statistics'] = '';
                d['icon-video'] = '';
            } else {
                marketGroupId = 0;
            }
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                odds = odds1x2FT ? odds1x2FT[rowIndex] : null;
                _populateOdds(d, odds, cache, template, _MarketDisplay._1X2_FT);
                odds = odds1x2FH ? odds1x2FH[rowIndex] : null;
                _populateOdds(d, odds, cache, template, _MarketDisplay._1X2_FH);
                odds = oddsDC ? oddsDC[rowIndex] : null;
                _populateOdds(d, odds, cache, template, _MarketDisplay.DC);
                d['row-index'] = oddsRowIndex++;
                d['bg-color'] = (templateRowIndex & 1) ? '#FFDDCC' : '#FFDDCC';
                var rowTemplateName = 'row-event-live';
                if (marketGroup && marketGroup[5]) {
                    rowTemplateName = 'row-event-live-yesno-1x2';
                }
                rows.push(template[rowTemplateName].getText(d));
            }
            rows.push(moreContent);
            templateRowIndex++
        }
        d['rows'] = rows.length > 0 ? rows.join('') : template['row-nodata'].getText(d);
        d['table'] = template['table'].getText(d);
        d['refresh-count'] = _syn.liveRefreshCount;
        d['refresh-button'] = _syn.liveCooldownCount ? _template['refresh-refreshing'].getText(d) : _template['refresh-countdown'].getText(d);
        d['odds-display-live'] = template['odds-display-live'].getText(d);
        var ret = 0;
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['refresh-count'] = _syn.liveRefreshCount;
            d['refresh-button'] = _syn.liveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-live'] = template['odds-display-live'].getText(d);
            ret = rows.length;
        } else if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
            _drawLoading();
            ret = 0;
        } else {
            d['odds-display-live'] = '';
            ret = 0;
        }
        return ret > 0;
    }

    function _populateNonliveSection(d) {
        $M('odds-display').clearRef();
        var template = _template;
        var cache = _nonliveCache;
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        _selectedOddId = $M('ticket').getOddIdOption();
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var oddsByMarketDisplayId = tagEventResult[5];
            var odds1x2FT = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay._1X2_FT] : null;
            var odds1x2FH = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay._1X2_FH] : null;
            var oddsDC = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.DC] : null;
            var rowCount = 0;
            if (odds1x2FT && rowCount < odds1x2FT.length) {
                rowCount = odds1x2FT.length;
            }
            if (odds1x2FH && rowCount < odds1x2FH.length) {
                rowCount = odds1x2FH.length;
            }
            if (oddsDC && rowCount < oddsDC.length) {
                rowCount = oddsDC.length;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                rows.push(template['row-tournament-nonlive'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? template['icon-video-nonlive'].getText(d) : '';
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = template['showtime-date-time'].getText(d);
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 1)) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = cache.getEventMoreOddsCount(eventResultId);
            d['live-or-nonlive'] = 'nonlive';
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                odds = odds1x2FT ? odds1x2FT[rowIndex] : null;
                _populateOdds(d, odds, cache, template, _MarketDisplay._1X2_FT);
                odds = odds1x2FH ? odds1x2FH[rowIndex] : null;
                _populateOdds(d, odds, cache, template, _MarketDisplay._1X2_FH);
                odds = oddsDC ? oddsDC[rowIndex] : null;
                _populateOdds(d, odds, cache, template, _MarketDisplay.DC);
                d['row-index'] = oddsRowIndex++;
                rows.push(template[(templateRowIndex & 1) ? 'row-event-alt' : 'row-event'].getText(d));
            }
            if ($M('more').isMoreOpened(eventResultId, 1)) {
                var moreContent = $M('more').getContent(_template['col-span'].getText({}));
                rows.push(moreContent);
            } else if ($M('more').isClosing(eventResultId, 1)) {
                var closingMoreContent = $M('more').getClosingContent();
                rows.push(closingMoreContent);
            }
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.nonliveRefreshCount;
        d['refresh-button'] = _syn.nonliveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        } else if (cache.isEmpty() && _syn.nonliveVersion == 0) {
            _drawLoading();
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        }
    }

    function _drawRefreshButtons(section) {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        if (section === undefined || section == 'live') {
            var a = document.getElementById('bu:od:refresh-live:button');
            if (a) {
                if (_syn.liveCooldownCount) {
                    a.innerHTML = _template['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _template['refresh'].getText();
                } else {
                    a.innerHTML = _template['refresh-countdown'].getText({
                        'refresh-count': _syn.liveRefreshCount
                    });
                }
            }
        }
        if (section === undefined || section == 'nonlive') {
            a = document.getElementById('bu:od:refresh-nonlive:button');
            if (a) {
                if (_syn.nonliveCooldownCount) {
                    a.innerHTML = _template['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _template['refresh'].getText();
                } else {
                    a.innerHTML = _template['refresh-countdown'].getText({
                        'refresh-count': _syn.nonliveRefreshCount
                    });
                }
            }
        }
    }

    function _populateOdds(d, odds, cache, template, marketDisplayId) {
        if (odds) {
            OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, _selectedOddId);
            OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
        } else {
            OddsUtility.clearOdds(d, marketDisplayId);
            OddsUtility.clearOddsIndicators(d, marketDisplayId);
        }
    }
}

function __Module_FT_1X2(refreshRate, sortType) {
    var _MarketDisplay = {
        _1X2_FT: 5
    };
    var _TemplateName = 'odds-display/1x2';
    var _self = this;
    var _template = null;
    var _liveCache = new __Cache_Event(sortType);
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _selectedOddId = null;
    var _syn = {
        waitingTemplate: false,
        liveDrawing: false,
        liveRefreshRate: refreshRate[0],
        liveRefreshCount: 0,
        liveCooldownCount: 0,
        liveFailureCount: 0,
        liveVersion: 0,
        nonliveDrawing: false,
        nonliveRefreshRate: refreshRate[1],
        nonliveRefreshCount: 0,
        nonliveCooldownCount: 0,
        nonliveFailureCount: 0,
        nonliveVersion: 0,
        nonliveWaitToDraw: false
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        if (_template) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_template) {
                    if (_syn.waitingTemplate) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                    if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
    };
    this.onIdle = function (data) {
        var version = data[0];
        var frameIndex = data[1];
        if (frameIndex == 0) {
            if (_syn.liveVersion < version) {
                _syn.liveVersion = version;
            }
            if (_liveCache.clearAdjustIndicators()) {
                _drawLive();
            }
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
            }
            if (_nonliveCache.clearAdjustIndicators()) {
                _drawNonlive();
            }
            _syn.nonliveDrawing = false;
        }
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var frameIndex = data[1];
        var clearAll = data[2];
        var frameData = data[3];
        var mediaData = data[4];
        var isChanged = false;
        if (frameIndex == 0) {
            if (_liveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.liveVersion < version) {
                _syn.liveVersion = version;
                if (_liveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (isChanged) {
                _drawLive();
                if (_syn.nonliveWaitToDraw) {
                    _syn.nonliveWaitToDraw = false;
                    _drawNonlive();
                }
                if (_liveCache.hasScoreChange()) {}
            }
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_nonliveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
                if (_nonliveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (isChanged) {
                if (_syn.liveVersion <= 0 && _nonliveCache.isEmpty()) {
                    _syn.nonliveWaitToDraw = true;
                } else {
                    _drawNonlive();
                }
            }
            _syn.nonliveDrawing = false;
        }
    };

    function _submitLive() {
        var sb = [];
        sb.push('odds-display/1x2-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=0&v=');
        sb.push(_syn.liveVersion);
        sb.push($M('more').getMoreParam(true));
        return TiLib.Ajax.sendRequest('1x2-live', sb.join(''));
    }

    function _submitNonlive() {
        var sb = [];
        sb.push('odds-display/1x2-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=1&v=');
        sb.push(_syn.nonliveVersion);
        sb.push($M('more').getMoreParam(false));
        return TiLib.Ajax.sendRequest('1x2-nonlive', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.liveCooldownCount) {
            _syn.liveCooldownCount--;
        } else if (_syn.liveDrawing) {
            if (_syn.liveFailureCount > 3) {
                _syn.liveDrawing = false;
            } else {
                _syn.liveFailureCount++;
            }
        } else if (_syn.liveRefreshCount > 0) {
            _drawRefreshButtons('live');
            _syn.liveRefreshCount--;
        } else {
            _syn.liveRefreshCount = _syn.liveRefreshRate;
            _syn.liveCooldownCount = 2;
            _syn.liveDrawing = true;
            _syn.liveFailureCount = 0;
            _submitLive();
            _drawRefreshButtons('live');
        }
        if (_syn.nonliveCooldownCount) {
            _syn.nonliveCooldownCount--;
        } else if (_syn.nonliveDrawing) {
            if (_syn.nonliveFailureCount > 3) {
                _syn.nonliveDrawing = false;
            } else {
                _syn.nonliveFailureCount++;
            }
        } else if (_syn.nonliveRefreshCount > 0) {
            _drawRefreshButtons('nonlive');
            _syn.nonliveRefreshCount--;
        } else {
            _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
            _syn.nonliveCooldownCount = 2;
            _syn.nonliveDrawing = true;
            _syn.nonliveFailureCount = 0;
            _submitNonlive();
            _drawRefreshButtons('nonlive');
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('live');
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('nonlive');
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('live');
                        }, 200);
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('nonlive');
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.liveVersion = 0;
            _syn.nonliveVersion = 0;
        } else if (_syn.liveDrawing || _syn.nonliveDrawing || _syn.liveCooldownCount || _syn.nonliveCooldownCount) {
            return;
        }
        _syn.liveRefreshCount = _syn.liveRefreshRate;
        _syn.liveCooldownCount = 2;
        _syn.liveDrawing = true;
        _syn.liveFailureCount = 0;
        _submitLive();
        _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
        _syn.nonliveCooldownCount = 2;
        _syn.nonliveDrawing = true;
        _syn.nonliveFailureCount = 0;
        _submitNonlive();
        _drawRefreshButtons();
    };
    this.refreshLive = function (clearAll) {
        if (!_syn.liveCooldownCount) {
            if (_syn.liveDrawing) {
                if (_syn.liveFailureCount > 3) {
                    _syn.liveDrawing = false;
                } else {
                    _syn.liveFailureCount++;
                }
            } else {
                if (clearAll) _syn.liveVersion = 0;
                _syn.liveRefreshCount = _syn.liveRefreshRate;
                _syn.liveCooldownCount = 2;
                _syn.liveDrawing = true;
                _syn.liveFailureCount = 0;
                _submitLive();
                _drawRefreshButtons('live');
            }
        }
    };
    this.refreshNonlive = function (clearAll) {
        if (!_syn.nonliveCooldownCount) {
            if (_syn.nonliveDrawing) {
                if (_syn.nonliveFailureCount > 3) {
                    _syn.nonliveDrawing = false;
                } else {
                    _syn.nonliveFailureCount++;
                }
            } else {
                if (clearAll) _syn.nonliveVersion = 0;
                _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
                _syn.nonliveCooldownCount = 2;
                _syn.nonliveDrawing = true;
                _syn.nonliveFailureCount = 0;
                _submitNonlive();
                _drawRefreshButtons('nonlive');
            }
        }
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _liveCache.sort(sortType);
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        _populateNonliveSection(d);
        var div = document.getElementById('module-odds-display');
        if (div) {
            div.innerHTML = _template['odds-display'].getText(d);
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
    }

    function _drawLive() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        var div = document.getElementById('odds-display-live');
        if (div) {
            div.innerHTML = d['odds-display-live'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _template['odds-display'].getText(d);
            }
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
    }

    function _drawNonlive() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var d = {};
        _populateNonliveSection(d);
        var div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.innerHTML = d['odds-display-nonlive'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _template['odds-display'].getText(d);
            }
        }
    }

    function _drawLoading() {
        if (_syn.liveVersion == 0 && _syn.nonliveVersion == 0 && _liveCache.isEmpty() && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_template && _template['loading']) {
                    text = _template['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _populateLiveSection(d) {
        $M('odds-display').clearRef();
        var template = _template;
        var cache = _liveCache;
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var marketGroupId = 0;
        var showMarketGroups = $M('odds-display').getDisplaySetting('market-showing') == 2 ? true : false;
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        _selectedOddId = $M('ticket').getOddIdOption();
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var odds1x2FT = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay._1X2_FT] : null;
            var rowCount = 0;
            var marketGroup = tagEventResult[6];
            if (marketGroup && marketGroup[0] != 0 && !showMarketGroups) {
                continue;
            }
            if (odds1x2FT && rowCount < odds1x2FT.length) {
                rowCount = odds1x2FT.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                var frozenOdds = eventResultExtra[8];
                var count = null;
                if (frozenOdds) {
                    count = isNaN(frozenOdds[_MarketDisplay._1X2_FT]) ? 0 : frozenOdds[_MarketDisplay._1X2_FT];
                    rowCount = Math.max(rowCount, count);
                    rowCount = rowCount > 1 ? 1 : rowCount;
                }
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            if (_mediaCache.hasLiveCenter(eventId) && (!marketGroup || marketGroup[0] == 0)) {
                d['icon-live-center'] = template['icon-live-center'].getText(d);
            } else {
                d['icon-live-center'] = null;
            }
            d['icon-video'] = _mediaCache.hasLiveVideo(eventId) ? template['icon-video'].getText(d) : null;
            d['ls-class'] = '';
            d['ls-tooltip'] = '';
            d['ls-id'] = 0;
            if (_mediaCache.hasLiveCenter(eventId)) {
                d['ls-class'] = 'ls-time-column';
                d['ls-tooltip'] = template['ls-tooltip'].getText();
                d['ls-id'] = d['event-id'];
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['home-score'] = eventResult[3];
            d['away-score'] = eventResult[4];
            d['vs'] = template['vs'].getText();
            d['score-separator'] = template['score-separator'].getText(d);
            d['score-class'] = cache.isScoreChanged(eventResultId) ? 'score-change' : '';
            var moreContent = '';
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 0)) {
                moreContent = $M('more').getContent(_template['col-span'].getText({}));
            } else if ($M('more').isClosing(eventResultId, 0)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = showMarketGroups ? cache.getEventResultMoreOddsCount(eventResultId) : cache.getEventMoreOddsCount(eventResultId);
            d['live-or-nonlive'] = 'live';
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            d['live-time'] = template['time-live'].getText(d);
            if (eventResultExtra) {
                var period = eventResultExtra[2];
                if (period > 0) {
                    if (period == 5) {
                        d['live-time'] = template['time-halftime'].getText(d);
                    } else {
                        d['live-time'] = OddsUtility.getLiveTime(period, cache.getLiveStartTime(eventResultId), eventResultExtra[3], eventResultExtra[4]);
                        var injuryTime = parseInt('' + eventResultExtra[7], 10);
                        if (injuryTime && injuryTime > 0) {
                            d['injuryTimeCount'] = injuryTime;
                            d['live-time'] += template['injury-time'].getText(d);
                        }
                    }
                }
            }
            var homeRedCards = '';
            var awayRedCards = '';
            if (eventResultExtra) {
                var redCardIndex;
                var redCardCount = eventResultExtra[5];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        homeRedCards += template['red-card'].getText(d);
                    }
                }
                redCardCount = eventResultExtra[6];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        awayRedCards += template['red-card'].getText(d);
                    }
                }
            }
            d['home-red-cards'] = homeRedCards;
            d['away-red-cards'] = awayRedCards;
            if (marketGroup && marketGroup[0]) {
                OddsUtility.populateMarketGroup(d, marketGroup);
                OddsUtility.populateMarketGroupTeams(d, marketGroup);
                if (marketGroupId != marketGroup[0]) {
                    marketGroupId = marketGroup[0];
                    rows.push(template['row-market-group'].getText(d));
                }
                d['icon-statistics'] = '';
                d['icon-video'] = '';
            } else {
                marketGroupId = 0;
            }
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds = odds1x2FT ? odds1x2FT[rowIndex] : null;
                _populateOdds(d, odds, cache, template, _MarketDisplay._1X2_FT);
                d['row-index'] = oddsRowIndex++;
                d['bg-color'] = (templateRowIndex & 1) ? '#FFDDCC' : '#FFDDCC';
                var rowTemplateName = 'row-event-live';
                if (marketGroup && marketGroup[5]) {
                    rowTemplateName = 'row-event-live-yesno-1x2';
                }
                rows.push(template[rowTemplateName].getText(d));
            }
            templateRowIndex++;
            rows.push(moreContent);
        }
        var ret = 0;
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['refresh-count'] = _syn.liveRefreshCount;
            d['refresh-button'] = _syn.liveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-live'] = template['odds-display-live'].getText(d);
            ret = rows.length;
        } else if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
            _drawLoading();
            ret = 0;
        } else {
            d['odds-display-live'] = '';
            ret = 0;
        }
        return ret > 0;
    }

    function _populateNonliveSection(d) {
        $M('odds-display').clearRef();
        var template = _template;
        var cache = _nonliveCache;
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        _selectedOddId = $M('ticket').getOddIdOption();
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var oddsByMarketDisplayId = tagEventResult[5];
            var odds1x2FT = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay._1X2_FT] : null;
            var rowCount = 0;
            if (odds1x2FT && rowCount < odds1x2FT.length) {
                rowCount = odds1x2FT.length;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                rows.push(template['row-tournament-nonlive'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? template['icon-video-nonlive'].getText(d) : '';
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = template['showtime-date-time'].getText(d);
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 1)) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = cache.getEventMoreOddsCount(eventResultId);
            d['live-or-nonlive'] = 'nonlive';
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds = odds1x2FT ? odds1x2FT[rowIndex] : null;
                _populateOdds(d, odds, cache, template, _MarketDisplay._1X2_FT);
                d['row-index'] = oddsRowIndex++;
                rows.push(template[(templateRowIndex & 1) ? 'row-event-alt' : 'row-event'].getText(d));
            }
            if ($M('more').isMoreOpened(eventResultId, 1)) {
                var moreContent = $M('more').getContent(_template['col-span'].getText({}));
                rows.push(moreContent);
            } else if ($M('more').isClosing(eventResultId, 1)) {
                var closingMoreContent = $M('more').getClosingContent();
                rows.push(closingMoreContent);
            }
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.nonliveRefreshCount;
        d['refresh-button'] = _syn.nonliveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        } else if (cache.isEmpty() && _syn.nonliveVersion == 0) {
            _drawLoading();
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        }
    }

    function _drawRefreshButtons(section) {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        if (section === undefined || section == 'live') {
            var a = document.getElementById('bu:od:refresh-live:button');
            if (a) {
                if (_syn.liveCooldownCount) {
                    a.innerHTML = _template['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _template['refresh'].getText();
                } else {
                    a.innerHTML = _template['refresh-countdown'].getText({
                        'refresh-count': _syn.liveRefreshCount
                    });
                }
            }
        }
        if (section === undefined || section == 'nonlive') {
            a = document.getElementById('bu:od:refresh-nonlive:button');
            if (a) {
                if (_syn.nonliveCooldownCount) {
                    a.innerHTML = _template['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _template['refresh'].getText();
                } else {
                    a.innerHTML = _template['refresh-countdown'].getText({
                        'refresh-count': _syn.nonliveRefreshCount
                    });
                }
            }
        }
    }

    function _populateOdds(d, odds, cache, template, marketDisplayId) {
        if (odds) {
            OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, _selectedOddId);
            OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
        } else {
            OddsUtility.clearOdds(d, marketDisplayId);
            OddsUtility.clearOddsIndicators(d, marketDisplayId);
        }
    }
}

function __Module_LiveDouble(refreshRate, sortType) {
    var _MarketDisplay = {
        FTime1X2: 5,
        FHalf1X2: 8,
        FTimeHDP: 1,
        FHalfHDP: 7,
        FTimeOU: 3,
        FHalfOU: 9,
        FTimeOE: 2,
        ML: 11,
        FTimeLS: 16
    };
    var _SportNameLive = {
        9: 'baseball'
    };
    var _TemplateName = 'odds-display/today-double-live';
    var _TemplateNameFavourite = 'left-column/favourite';
    var _self = this;
    var _template = null;
    var _templateFavourite = null;
    var _liveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _syn = {
        liveWaitingTemplate: false,
        liveDrawing: false,
        liveRefreshRate: refreshRate,
        liveRefreshCount: 0,
        liveCooldownCount: 0,
        liveFailureCount: 0,
        liveVersion: 0,
        favouriteWaitingTemplate: false
    };
    this.initiate = function () {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        var extentLive = _SportNameLive[sportId];
        if (!extentLive) extentLive = 'soccer';
        var templateText = $P.getTemplate(_TemplateName + '-' + extentLive);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        templateText = $P.getTemplate(_TemplateNameFavourite);
        if (templateText) {
            _templateFavourite = TiLib.Template.createTemplates(templateText);
        }
        if (_template || _templateFavourite) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        var extentLive = _SportNameLive[sportId];
        if (!extentLive) extentLive = 'soccer';
        if (name == _TemplateName + '-' + extentLive) {
            var templateText = $P.getTemplate(_TemplateName + '-' + extentLive);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_template) {
                    if (_syn.liveWaitingTemplate) {
                        _syn.liveWaitingTemplate = false;
                        _drawLive();
                    }
                    if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
        if (name == _TemplateNameFavourite) {
            var templateText = $P.getTemplate(_TemplateNameFavourite);
            if (templateText) {
                _templateFavourite = TiLib.Template.createTemplates(templateText);
                if (_templateFavourite) {
                    if (_syn.favouriteWaitingTemplate) {
                        _syn.favouriteWaitingTemplate = false;
                        _drawLive();
                    }
                }
            }
        }
    };
    this.onIdle = function (version) {
        if (_syn.liveVersion < version) {
            _syn.liveVersion = version;
        }
        _liveCache.clearAdjustIndicators();
        _draw();
        _syn.liveDrawing = false;
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var clearAll = data[1];
        var liveData = data[2];
        var mediaData = data[3];
        var favouriteData = data[4];
        var isChanged = false;
        if (_liveCache.clearAdjustIndicators()) {
            isChanged = true;
        }
        if (clearAll || _syn.liveVersion < version) {
            _syn.liveVersion = version;
            if (_liveCache.update(clearAll, liveData, $M('odds-display').getDisplaySetting('price-style'))) {
                isChanged = true;
            }
        }
        if (_mediaCache.update(mediaData)) {
            isChanged = true;
        }
        if (favouriteData) {
            $M('favourite').onUpdate(favouriteData);
        }
        if (isChanged) {
            _draw();
        }
        if (!isChanged) {
            _drawLive();
        }
        _syn.liveDrawing = false;
    };

    function _submitLive() {
        var sb = [];
        sb.push('odds-display/live-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&v=');
        sb.push(_syn.liveVersion);
        sb.push($M('more').getMoreParam(true));
        return TiLib.Ajax.sendRequest('live-double', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.liveCooldownCount) {
            _syn.liveCooldownCount--;
        } else if (_syn.liveDrawing) {
            if (_syn.liveFailureCount > 3) {
                _syn.liveDrawing = false;
            } else {
                _syn.liveFailureCount++;
            }
        } else if (_syn.liveRefreshCount > 0) {
            _drawRefreshButtons();
            _syn.liveRefreshCount--;
        } else {
            _syn.liveRefreshCount = _syn.liveRefreshRate;
            _syn.liveCooldownCount = 2;
            _syn.liveDrawing = true;
            _syn.liveFailureCount = 0;
            _submitLive();
            _drawRefreshButtons();
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('live');
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('live');
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onClick = function (event) {
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    }

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'od') {
                switch (atom[2]) {
                case 'fav':
                    if (count >= 4) {
                        if (atom[3] == 'add-tournament') {
                            var eventResults = _liveCache.getEventResultIdsByTournament(parseInt(atom[4]));
                            $M('favourite').addRemoveFavourite(atom[3], eventResults, atom[4]);
                        } else {
                            $M('favourite').addRemoveFavourite(atom[3], atom[4]);
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.liveVersion = 0;
        } else if (_syn.liveDrawing || _syn.liveCooldownCount) {
            return;
        }
        _syn.liveRefreshCount = _syn.liveRefreshRate;
        _syn.liveCooldownCount = 2;
        _syn.liveDrawing = true;
        _syn.liveFailureCount = 0;
        _submitLive();
        _drawRefreshButtons();
    };
    this.refreshLive = function (clearAll) {
        if (!_syn.liveCooldownCount) {
            if (_syn.liveDrawing) {
                if (_syn.liveFailureCount > 3) {
                    _syn.liveDrawing = false;
                } else {
                    _syn.liveFailureCount++;
                }
            } else {
                if (clearAll) _syn.liveVersion = 0;
                _syn.liveRefreshCount = _syn.liveRefreshRate;
                _syn.liveCooldownCount = 2;
                _syn.liveDrawing = true;
                _syn.liveFailureCount = 0;
                _submitLive();
                _drawRefreshButtons();
            }
        }
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _liveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_template || !_templateFavourite) {
            _syn.liveWaitingTemplate = true;
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        _populateLiveSection(d);
        var div = document.getElementById('module-odds-display');
        if (div) {
            div.innerHTML = _template['odds-display'].getText(d);
        }
        div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.parentNode.removeChild(div);
        }
    }

    function _drawLive() {
        if (!_template || _templateFavourite) {
            _syn.liveWaitingTemplate = true;
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        _populateLiveSection(d);
        var div = document.getElementById('odds-display-live');
        if (div) {
            div.innerHTML = d['odds-display-live'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div && _syn.liveVersion > 0) {
                div.innerHTML = _template['odds-display'].getText(d);
            }
        }
        div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.parentNode.removeChild(div);
        }
    }

    function _drawLoading() {
        if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_template && _template['loading']) {
                    text = _template['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _populateLiveSection(d) {
        $M('odds-display').clearRef();
        var template = _template;
        var favTemplate = _templateFavourite;
        var cache = _liveCache;
        var favCache = $M('favourite').getCache();
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var marketGroupId = 0;
        var showMarketGroups = $M('odds-display').getDisplaySetting('market-showing') == 2 ? true : false;
        var selectedOddId = $M('ticket').getOddIdOption();
        d['market-page'] = template['market-page-live'].getText();
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var marketGroup = tagEventResult[6];
            if (marketGroup && marketGroup[0] != 0 && !showMarketGroups) {
                continue;
            }
            var oddsFTime1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTime1X2] : null;
            var oddsFHalf1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalf1X2] : null;
            var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
            var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
            var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
            var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
            var oddsFTimeLS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeLS] : null;
            var rowCount = 0;
            if (oddsFTime1X2 && rowCount < oddsFTime1X2.length) {
                rowCount = oddsFTime1X2.length;
            }
            if (oddsFHalf1X2 && rowCount < oddsFHalf1X2.length) {
                rowCount = oddsFHalf1X2.length;
            }
            if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
                rowCount = oddsFTimeHDP.length;
            }
            if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
                rowCount = oddsFHalfHDP.length;
            }
            if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
                rowCount = oddsFTimeOU.length;
            }
            if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
                rowCount = oddsFHalfOU.length;
            }
            if (oddsFTimeLS && rowCount < oddsFTimeLS.length) {
                rowCount = oddsFTimeLS.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                var frozenOdds = eventResultExtra[8];
                var count = null;
                if (frozenOdds) {
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeHDP]) ? 0 : frozenOdds[_MarketDisplay.FTimeHDP];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalfHDP]) ? 0 : frozenOdds[_MarketDisplay.FHalfHDP];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeOU]) ? 0 : frozenOdds[_MarketDisplay.FTimeOU];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalfOU]) ? 0 : frozenOdds[_MarketDisplay.FHalfOU];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FTime1X2]) ? 0 : frozenOdds[_MarketDisplay.FTime1X2];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalf1X2]) ? 0 : frozenOdds[_MarketDisplay.FHalf1X2];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeLS]) ? 0 : frozenOdds[_MarketDisplay.FTimeLS];
                    rowCount = Math.max(rowCount, count);
                    rowCount = rowCount > 1 ? 1 : rowCount;
                }
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                marketGroupId = 0;
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                if (favCache.hasTournament(tournament[0])) {
                    favourite = 'icon-live-tournament-remove';
                } else {
                    favourite = 'icon-live-tournament-add';
                }
                d['icon-favourite-tournament'] = favTemplate[favourite].getText(d);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasLiveVideo(eventId) ? template['icon-video'].getText(d) : null;
            d['ls-class'] = '';
            d['ls-tooltip'] = '';
            d['ls-id'] = 0;
            if (_mediaCache.hasLiveCenter(eventId)) {
                d['ls-class'] = 'ls-time-column';
                d['ls-tooltip'] = template['ls-tooltip'].getText();
                d['ls-id'] = d['event-id'];
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['home-score'] = eventResult[3];
            d['away-score'] = eventResult[4];
            d['score-separator'] = template['score-separator'].getText(d);
            d['draw'] = template['draw'].getText();
            d['vs'] = template['vs'].getText();
            d['score-class'] = cache.isScoreChanged(eventResultId) ? 'score-change' : '';
            var moreContent = '';
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 0)) {
                moreContent = $M('more').getContent(11);
            } else if ($M('more').isClosing(eventResultId, 0)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = showMarketGroups ? cache.getEventResultMoreOddsCount(eventResultId) : cache.getEventMoreOddsCount(eventResultId);
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            if (marketGroup && marketGroup[0]) {
                OddsUtility.populateMarketGroup(d, marketGroup);
                OddsUtility.populateMarketGroupTeams(d, marketGroup);
                if (marketGroupId != marketGroup[0]) {
                    marketGroupId = marketGroup[0];
                    rows.push(template['row-market-group'].getText(d));
                }
                d['icon-statistics'] = '';
                d['icon-video'] = '';
            } else {
                marketGroupId = 0;
            }
            if (favCache.hasEventResult(eventResultId) || favCache.hasTournament(tournamentId)) {
                favourite = 'icon-live-event-remove';
            } else {
                favourite = 'icon-live-event-add';
            }
            d['icon-favourite-event'] = favTemplate[favourite].getText(d);
            d['live-time'] = template['time-live'].getText(d);
            if (eventResultExtra) {
                var period = eventResultExtra[2];
                if (period > 0) {
                    if (period == 5) {
                        d['live-time'] = template['time-halftime'].getText(d);
                    } else {
                        d['live-time'] = OddsUtility.getLiveTime(period, cache.getLiveStartTime(eventResultId), eventResultExtra[3], eventResultExtra[4]);
                        var injuryTime = parseInt('' + eventResultExtra[7], 10);
                        if (injuryTime && injuryTime > 0) {
                            d['injuryTimeCount'] = injuryTime;
                            d['live-time'] += template['injury-time'].getText(d);
                        }
                    }
                }
            }
            var homeRedCards = '';
            var awayRedCards = '';
            if (eventResultExtra) {
                var redCardIndex;
                var redCardCount = eventResultExtra[5];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        homeRedCards += template['red-card'].getText(d);
                    }
                }
                redCardCount = eventResultExtra[6];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        awayRedCards += template['red-card'].getText(d);
                    }
                }
            }
            d['home-red-cards'] = homeRedCards;
            d['away-red-cards'] = awayRedCards;
            d['sub-row'] = '';
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                var has1X2 = false;
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['home-color-class'] = hdp > 0 ? 'Red' : 'Blue';
                d['away-color-class'] = hdp < 0 ? 'Red' : 'Blue';
                odds = oddsFTime1X2 ? oddsFTime1X2[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTime1X2);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTime1X2);
                }
                odds = oddsFHalf1X2 ? oddsFHalf1X2[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalf1X2);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalf1X2);
                }
                odds = oddsFTimeLS ? oddsFTimeLS[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeLS);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeLS);
                }
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeHDP);
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfHDP);
                }
                odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOU);
                }
                odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOU);
                }
                odds = oddsFTimeLS ? oddsFTimeLS[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeLS);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeLS);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeLS);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeLS);
                }
                d['row-index'] = oddsRowIndex;
                var rowTemplateName;
                if (marketGroup && marketGroup[5]) {
                    rowTemplateName = 'row-event-yesno';
                    if (has1X2) {
                        rowTemplateName = 'row-event-yesno-1x2';
                    }
                } else if (!has1X2 && template['row-event-no1x2']) {
                    rowTemplateName = 'row-event-no1x2';
                } else {
                    rowTemplateName = 'row-event';
                }
                d['bg-color'] = (templateRowIndex & 1) ? '#FFDDCC' : '#FFDDCC';
                rows.push(template[rowTemplateName].getText(d));
                oddsRowIndex++;
                d['icon-statistics'] = null;
                d['icon-video'] = null;
                d['ls-class'] = '';
                d['ls-id'] = 0;
                d['ls-tooltip'] = '';
                d['home-score'] = null;
                d['away-score'] = null;
                d['score-separator'] = null;
                d['draw'] = null;
                d['vs'] = null;
                d['score-class'] = null;
                d['icon-more'] = null;
                d['live-time'] = null;
                d['home-red-cards'] = null;
                d['away-red-cards'] = null;
                d['original-home'] = null;
                d['original-away'] = null;
                d['home'] = null;
                d['away'] = null;
                d['tv-channel'] = null;
                d['sub-row'] = 'subrow';
                d['icon-favourite-event'] = null;
            }
            rows.push(moreContent);
            templateRowIndex++;
        }
        var ret = 0;
        d['refresh-count'] = _syn.liveRefreshCount;
        d['refresh-button'] = _syn.liveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['additional-class'] = _getAdditionalClass();
            d['table'] = template['table'].getText(d);
            d['odds-display-live'] = template['odds-display-live'].getText(d);
            ret = rows.length;
        } else if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
            _drawLoading();
            ret = 0;
        } else {
            d['rows'] = template['row-nodata'].getText();
            d['table'] = template['table'].getText(d);
            d['odds-display-live'] = template['odds-display-live'].getText(d);
            ret = 0;
        }
        return ret;
    }

    function _getAdditionalClass() {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        switch (parseInt(sportId)) {
        case 2:
            return _template['basketball-additional-class'].getText();
        default:
            return '';
        }
    }

    function _drawRefreshButtons() {
        if (!_template) {
            _syn.liveWaitingTemplate = true;
            return;
        }
        var a = document.getElementById('bu:od:refresh-live:button');
        if (a) {
            if (_syn.liveCooldownCount) {
                a.innerHTML = _template['refresh-refreshing'].getText();
            } else if (a.isHover) {
                a.innerHTML = _template['refresh'].getText();
            } else {
                a.innerHTML = _template['refresh-countdown'].getText({
                    'refresh-count': _syn.liveRefreshCount
                });
            }
        }
    }
}

function __Module_LiveSingle(refreshRate, sortType) {
    var _MarketDisplay = {
        FTime1X2: 5,
        FHalf1X2: 8,
        FTimeHDP: 1,
        FHalfHDP: 7,
        FTimeOU: 3,
        FHalfOU: 9,
        FTimeOE: 2,
        ML: 11
    };
    var _TemplateNameLive = 'odds-display/today-single-live';
    var _TemplateNameFavourite = 'left-column/favourite';
    var _self = this;
    var _templateLive = null;
    var _templateFavourite = null;
    var _liveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _syn = {
        liveWaitingTemplate: false,
        liveDrawing: false,
        liveRefreshRate: refreshRate,
        liveRefreshCount: 0,
        liveCooldownCount: 0,
        liveFailureCount: 0,
        liveVersion: 0,
        favouriteWaitingTemplate: false
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateNameLive);
        if (templateText) {
            _templateLive = TiLib.Template.createTemplates(templateText);
        }
        templateText = $P.getTemplate(_TemplateNameFavourite);
        if (templateText) {
            _templateFavourite = TiLib.Template.createTemplates(templateText);
        }
        if (_templateLive || _templateFavourite) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateNameLive) {
            var templateText = $P.getTemplate(_TemplateNameLive);
            if (templateText) {
                _templateLive = TiLib.Template.createTemplates(templateText);
                if (_templateLive) {
                    if (_syn.liveWaitingTemplate) {
                        _syn.liveWaitingTemplate = false;
                        _drawLive();
                    }
                    if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
        if (name == _TemplateNameFavourite) {
            var templateText = $P.getTemplate(_TemplateNameFavourite);
            if (templateText) {
                _templateFavourite = TiLib.Template.createTemplates(templateText);
                if (_templateFavourite) {
                    if (_syn.favouriteWaitingTemplate) {
                        _syn.favouriteWaitingTemplate = false;
                        if (!_syn.liveDrawing && !_syn.nonliveDrawing) {
                            _drawLive();
                        }
                    }
                }
            }
        }
    };
    this.onIdle = function (data) {
        var version = data[0];
        if (_syn.liveVersion < version) {
            _syn.liveVersion = version;
        }
        _liveCache.clearAdjustIndicators();
        _drawLive();
        _syn.liveDrawing = false;
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var clearAll = data[1];
        var frameData = data[2];
        var mediaData = data[3];
        var favouriteData = data[4];
        var isChanged = false;
        if (_liveCache.clearAdjustIndicators()) {
            isChanged = true;
        }
        if (clearAll || _syn.liveVersion < version) {
            _syn.liveVersion = version;
            if (_liveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                isChanged = true;
            }
        }
        if (_mediaCache.update(mediaData)) {
            isChanged = true;
        }
        if (favouriteData) {
            $M('favourite').onUpdate(favouriteData);
        }
        if (isChanged) {
            _drawLive();
        }
        if (!isChanged) {
            _drawLive();
        }
        _syn.liveDrawing = false;
    };

    function _submitLive() {
        var sb = [];
        sb.push('odds-display/live-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&v=');
        sb.push(_syn.liveVersion);
        sb.push($M('more').getMoreParam(true));
        return TiLib.Ajax.sendRequest('live-single', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.liveCooldownCount) {
            _syn.liveCooldownCount--;
        } else if (_syn.liveDrawing) {
            if (_syn.liveFailureCount > 3) {
                _syn.liveDrawing = false;
            } else {
                _syn.liveFailureCount++;
            }
        } else if (_syn.liveRefreshCount > 0) {
            _drawRefreshButtons();
            _syn.liveRefreshCount--;
        } else {
            _syn.liveRefreshCount = _syn.liveRefreshRate;
            _syn.liveCooldownCount = 2;
            _syn.liveDrawing = true;
            _syn.liveFailureCount = 0;
            _submitLive();
            _drawRefreshButtons();
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons();
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons();
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onClick = function (event) {
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    }

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'od') {
                switch (atom[2]) {
                case 'fav':
                    if (count >= 4) {
                        if (atom[3] == 'add-tournament') {
                            var eventResults = _liveCache.getEventResultIdsByTournament(parseInt(atom[4]));
                            $M('favourite').addRemoveFavourite(atom[3], eventResults, atom[4]);
                        } else {
                            $M('favourite').addRemoveFavourite(atom[3], atom[4]);
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.liveVersion = 0;
        } else if (_syn.liveDrawing || _syn.liveCooldownCount) {
            return;
        }
        _syn.liveRefreshCount = _syn.liveRefreshRate;
        _syn.liveCooldownCount = 2;
        _syn.liveDrawing = true;
        _syn.liveFailureCount = 0;
        _submitLive();
        _drawRefreshButtons();
    };
    this.refreshLive = function (clearAll) {
        if (!_syn.liveCooldownCount) {
            if (_syn.liveDrawing) {
                if (_syn.liveFailureCount > 3) {
                    _syn.liveDrawing = false;
                } else {
                    _syn.liveFailureCount++;
                }
            } else {
                if (clearAll) _syn.liveVersion = 0;
                _syn.liveRefreshCount = _syn.liveRefreshRate;
                _syn.liveCooldownCount = 2;
                _syn.liveDrawing = true;
                _syn.liveFailureCount = 0;
                _submitLive();
                _drawRefreshButtons();
            }
        }
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _liveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_templateLive || !_templateFavourite) {
            _syn.liveWaitingTemplate = true;
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        _populateLiveSection(d);
        var div = document.getElementById('module-odds-display');
        if (div) {
            div.innerHTML = _templateLive['odds-display'].getText(d);
        }
        div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.parentNode.removeChild(div);
        }
    }

    function _drawLive() {
        if (!_templateLive || !_templateFavourite) {
            _syn.liveWaitingTemplate = true;
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        _populateLiveSection(d);
        var div = document.getElementById('odds-display-live');
        if (div) {
            div.innerHTML = d['odds-display-live'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _templateLive['odds-display'].getText(d);
            }
        }
        div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.parentNode.removeChild(div);
        }
    }

    function _drawLoading() {
        if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_templateLive && _templateLive['loading']) {
                    text = _templateLive['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _populateLiveSection(d) {
        $M('odds-display').clearRef();
        var template = _templateLive;
        var favTemplate = _templateFavourite;
        var cache = _liveCache;
        var favCache = $M('favourite').getCache();
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var marketGroupId = 0;
        var showMarketGroups = $M('odds-display').getDisplaySetting('market-showing') == 2 ? true : false;
        var selectedOddId = $M('ticket').getOddIdOption();
        var moreContent = '';
        var prevEventResultId = -1;
        d['market-page'] = template['market-page-live'].getText();
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var marketGroup = tagEventResult[6];
            if (marketGroup && marketGroup[0] != 0 && !showMarketGroups) {
                continue;
            }
            var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
            var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
            var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
            var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
            var rowCount = 0;
            if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
                rowCount = oddsFTimeHDP.length;
            }
            if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
                rowCount = oddsFHalfHDP.length;
            }
            if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
                rowCount = oddsFTimeOU.length;
            }
            if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
                rowCount = oddsFHalfOU.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                var frozenOdds = eventResultExtra[8];
                var count = null;
                if (frozenOdds) {
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeHDP]) ? 0 : frozenOdds[_MarketDisplay.FTimeHDP];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalfHDP]) ? 0 : frozenOdds[_MarketDisplay.FHalfHDP];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeOU]) ? 0 : frozenOdds[_MarketDisplay.FTimeOU];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalfOU]) ? 0 : frozenOdds[_MarketDisplay.FHalfOU];
                    rowCount = Math.max(rowCount, count);
                    rowCount = rowCount > 1 ? 1 : rowCount;
                }
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                marketGroupId = 0;
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                if (favCache.hasTournament(tournament[0])) {
                    favourite = 'icon-live-tournament-remove';
                } else {
                    favourite = 'icon-live-tournament-add';
                }
                d['icon-favourite-tournament'] = favTemplate[favourite].getText(d);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasLiveVideo(eventId) ? template['icon-video'].getText(d) : null;
            d['ls-class'] = '';
            d['ls-tooltip'] = '';
            d['ls-id'] = 0;
            if (_mediaCache.hasLiveCenter(eventId)) {
                d['ls-class'] = 'ls-time-column';
                d['ls-tooltip'] = template['ls-tooltip'].getText();
                d['ls-id'] = d['event-id'];
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['home-score'] = eventResult[3];
            d['away-score'] = eventResult[4];
            d['score-separator'] = template['score-separator'].getText(d);
            d['draw'] = template['draw'].getText();
            d['vs'] = template['vs'].getText();
            d['score-class'] = cache.isScoreChanged(eventResultId) ? 'score-change' : '';
            var moreContent = '';
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 0)) {
                moreContent = $M('more').getContent(16);
            } else if ($M('more').isClosing(eventResultId, 0)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = showMarketGroups ? cache.getEventResultMoreOddsCount(eventResultId) : cache.getEventMoreOddsCount(eventResultId);
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            if (marketGroup && marketGroup[0]) {
                OddsUtility.populateMarketGroup(d, marketGroup);
                OddsUtility.populateMarketGroupTeams(d, marketGroup);
                if (marketGroupId != marketGroup[0]) {
                    marketGroupId = marketGroup[0];
                    rows.push(template['row-market-group'].getText(d));
                }
                d['icon-statistics'] = '';
                d['icon-video'] = '';
            } else {
                marketGroupId = 0;
            }
            if (favCache.hasEventResult(eventResultId) || favCache.hasTournament(tournamentId)) {
                favourite = 'icon-live-event-remove';
            } else {
                favourite = 'icon-live-event-add';
            }
            d['icon-favourite-event'] = favTemplate[favourite].getText(d);
            d['live-time'] = template['time-live'].getText(d);
            if (eventResultExtra) {
                var period = eventResultExtra[2];
                if (period > 0) {
                    if (period == 5) {
                        d['live-time'] = template['time-halftime'].getText(d);
                    } else {
                        d['live-time'] = OddsUtility.getLiveTime(period, cache.getLiveStartTime(eventResultId), eventResultExtra[3], eventResultExtra[4]);
                        var injuryTime = parseInt('' + eventResultExtra[7], 10);
                        if (injuryTime && injuryTime > 0) {
                            d['injuryTimeCount'] = injuryTime;
                            d['live-time'] += template['injury-time'].getText(d);
                        }
                    }
                }
            }
            var homeRedCards = '';
            var awayRedCards = '';
            if (eventResultExtra) {
                var redCardIndex;
                var redCardCount = eventResultExtra[5];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        homeRedCards += template['red-card'].getText(d);
                    }
                }
                redCardCount = eventResultExtra[6];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        awayRedCards += template['red-card'].getText(d);
                    }
                }
            }
            d['home-red-cards'] = homeRedCards;
            d['away-red-cards'] = awayRedCards;
            d['sub-row'] = '';
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['home-color-class'] = hdp > 0 ? 'Red' : 'Blue';
                d['away-color-class'] = hdp < 0 ? 'Red' : 'Blue';
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeHDP);
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfHDP);
                }
                odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOU);
                }
                odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOU);
                }
                d['row-index'] = oddsRowIndex;
                var rowTemplateName = 'row-event';
                if (marketGroup && marketGroup[4] && marketGroup[5] == 1) {
                    rowTemplateName = 'row-event-yesno';
                }
                d['bg-color'] = (templateRowIndex & 1) ? '#FFDDCC' : '#FFDDCC';
                rows.push(template[rowTemplateName].getText(d));
                oddsRowIndex++;
                d['icon-statistics'] = null;
                d['icon-video'] = null;
                d['ls-class'] = '';
                d['ls-id'] = 0;
                d['ls-tooltip'] = '';
                d['home-score'] = null;
                d['away-score'] = null;
                d['score-separator'] = null;
                d['draw'] = null;
                d['vs'] = null;
                d['score-class'] = null;
                d['icon-more'] = null;
                d['live-time'] = null;
                d['home-red-cards'] = null;
                d['away-red-cards'] = null;
                d['original-home'] = null;
                d['original-away'] = null;
                d['home'] = null;
                d['away'] = null;
                d['tv-channel'] = null;
                d['sub-row'] = 'subrow';
                d['icon-favourite-event'] = null;
            }
            rows.push(moreContent);
            templateRowIndex++;
        }
        var ret = 0;
        d['refresh-count'] = _syn.liveRefreshCount;
        d['refresh-button'] = _syn.liveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['additional-class'] = _getAdditionalClass();
            d['table'] = template['table'].getText(d);
            d['odds-display-live'] = template['odds-display-live'].getText(d);
            ret = rows.length;
        } else if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
            _drawLoading();
            ret = 0;
        } else {
            d['rows'] = template['row-nodata'].getText();
            d['table'] = template['table'].getText(d);
            d['odds-display-live'] = template['odds-display-live'].getText(d);
            ret = 0;
        }
        return ret;
    }

    function _getAdditionalClass() {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        switch (parseInt(sportId)) {
        case 2:
            return _templateLive['basketball-additional-class'].getText();
        default:
            return '';
        }
    }

    function _drawRefreshButtons() {
        if (!_templateLive) {
            _syn.liveWaitingTemplate = true;
            return;
        }
        var a = document.getElementById('bu:od:refresh-live:button');
        if (a) {
            if (_syn.liveCooldownCount) {
                a.innerHTML = _templateLive['refresh-refreshing'].getText();
            } else if (a.isHover) {
                a.innerHTML = _templateLive['refresh'].getText();
            } else {
                a.innerHTML = _templateLive['refresh-countdown'].getText({
                    'refresh-count': _syn.liveRefreshCount
                });
            }
        }
    }
}

function __Module_TodayDouble(refreshRate, sortType) {
    var _MarketDisplay = {
        FTime1X2: 5,
        FHalf1X2: 8,
        FTimeHDP: 1,
        FHalfHDP: 7,
        FTimeOU: 3,
        FHalfOU: 9,
        FTimeOE: 2,
        FHalfOE: 12,
        ML: 11,
        FTimeLS: 16
    };
    var _SportNameNonlive = {
        1: 'soccer',
        2: 'basketball',
        3: 'football',
        7: 'motor',
        9: 'baseball',
        13: 'boxing',
        14: 'cricket',
        17: 'handball',
        28: 'winter',
        31: 'boxing'
    };
    var _SportNameLive = {
        9: 'baseball'
    };
    var _NonliveColSpan = {
        1: 11,
        2: 10,
        3: 10,
        7: 8,
        9: 10,
        13: 7,
        14: 7,
        17: 7,
        28: 6,
        31: 7
    };
    var _TemplateNameLive = 'odds-display/today-double-live';
    var _TemplateNameNonlive = 'odds-display/today-double-nonlive';
    var _TemplateNameFavourite = 'left-column/favourite';
    var _self = this;
    var _templateLive = null;
    var _templateNonlive = null;
    var _templateFavourite = null;
    var _liveCache = new __Cache_Event(sortType);
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _daylightPeriod = 0;
    var _syn = {
        liveWaitingTemplate: false,
        liveDrawing: false,
        liveRefreshRate: refreshRate[0],
        liveRefreshCount: 0,
        liveCooldownCount: 0,
        liveFailureCount: 0,
        liveVersion: 0,
        nonliveWaitingTemplate: false,
        nonliveDrawing: false,
        nonliveRefreshRate: refreshRate[1],
        nonliveRefreshCount: 0,
        nonliveCooldownCount: 0,
        nonliveFailureCount: 0,
        nonliveVersion: 0,
        nonliveWaitToDraw: false,
        favouriteWaitingTemplate: false
    };
    this.initiate = function () {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        var extentLive = _SportNameLive[sportId];
        if (!extentLive) extentLive = 'soccer';
        var templateText = $P.getTemplate(_TemplateNameLive + '-' + extentLive);
        if (templateText) {
            _templateLive = TiLib.Template.createTemplates(templateText);
        }
        var extentNonlive = _SportNameNonlive[sportId];
        if (!extentNonlive) extentNonlive = 'motor';
        templateText = $P.getTemplate(_TemplateNameNonlive + '-' + extentNonlive);
        if (templateText) {
            _templateNonlive = TiLib.Template.createTemplates(templateText);
        }
        templateText = $P.getTemplate(_TemplateNameFavourite);
        if (templateText) {
            _templateFavourite = TiLib.Template.createTemplates(templateText);
        }
        if (_templateNonlive || _templateLive || _templateFavourite) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        var extentLive = _SportNameLive[sportId];
        if (!extentLive) extentLive = 'soccer';
        if (name == _TemplateNameLive + '-' + extentLive) {
            var templateText = $P.getTemplate(_TemplateNameLive + '-' + extentLive);
            if (templateText) {
                _templateLive = TiLib.Template.createTemplates(templateText);
                if (_templateLive) {
                    if (_syn.liveWaitingTemplate) {
                        _syn.liveWaitingTemplate = false;
                        _drawLive();
                    }
                    if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
        var extentNonlive = _SportNameNonlive[sportId];
        if (!extentNonlive) extentNonlive = 'motor';
        if (name == _TemplateNameNonlive + '-' + extentNonlive) {
            var templateText = $P.getTemplate(_TemplateNameNonlive + '-' + extentNonlive);
            if (templateText) {
                _templateNonlive = TiLib.Template.createTemplates(templateText);
                if (_templateNonlive) {
                    if (_syn.nonliveWaitingTemplate) {
                        _syn.nonliveWaitingTemplate = false;
                        _drawNonlive();
                    }
                    if (_syn.nonliveVersion == 0 && _nonliveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
        if (name == _TemplateNameFavourite) {
            var templateText = $P.getTemplate(_TemplateNameFavourite);
            if (templateText) {
                _templateFavourite = TiLib.Template.createTemplates(templateText);
                if (_templateFavourite) {
                    if (_syn.favouriteWaitingTemplate) {
                        _syn.favouriteWaitingTemplate = false;
                        _drawLive();
                        _drawNonlive();
                    }
                }
            }
        }
    };
    this.onIdle = function (data) {
        var version = data[0];
        var frameIndex = data[1];
        if (frameIndex == 0) {
            if (_syn.liveVersion < version) {
                _syn.liveVersion = version;
            }
            _liveCache.clearAdjustIndicators();
            _drawLive();
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
            }
            _nonliveCache.clearAdjustIndicators();
            _drawNonlive();
            _syn.nonliveDrawing = false;
        }
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var frameIndex = data[1];
        var clearAll = data[2];
        var frameData = data[3];
        var mediaData = data[4];
        var daylightType = data[5];
        var favouriteData = data[6];
        var isChanged = false;
        if (frameIndex == 0) {
            if (_liveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.liveVersion < version) {
                _syn.liveVersion = version;
                if (_liveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (favouriteData) {
                $M('favourite').onUpdate(favouriteData);
            }
            if (isChanged) {
                _drawLive();
                if (_syn.nonliveWaitToDraw) {
                    _syn.nonliveWaitToDraw = false;
                    _drawNonlive();
                }
            }
            if (!isChanged) {
                _drawLive();
            }
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_nonliveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
                if (_nonliveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (favouriteData) {
                $M('favourite').onUpdate(favouriteData);
            }
            if (daylightType && daylightType.length >= 2) {
                _daylightPeriod = daylightType[1];
                $M('odds-display').setDisplaySetting('daylight-type-period', daylightType[1]);
                $M('odds-display').setDisplaySetting('daylight-type', daylightType[0]);
            }
            if (isChanged) {
                if (_syn.liveVersion <= 0 && _nonliveCache.isEmpty()) {
                    _syn.nonliveWaitToDraw = true;
                } else {
                    _drawNonlive();
                }
            }
            if (!isChanged) {
                _drawNonlive();
            }
            _syn.nonliveDrawing = false;
        }
    };

    function _submitLive() {
        var sb = [];
        sb.push('odds-display/today-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=0&v=');
        sb.push(_syn.liveVersion);
        sb.push($M('more').getMoreParam(true));
        return TiLib.Ajax.sendRequest('today-double-live', sb.join(''));
    }

    function _submitNonlive() {
        var sb = [];
        sb.push('odds-display/today-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=1&v=');
        sb.push(_syn.nonliveVersion);
        sb.push('&dl=');
        sb.push($M('odds-display').getDisplaySetting('daylight-type'));
        sb.push($M('more').getMoreParam(false));
        return TiLib.Ajax.sendRequest('today-double-nonlive', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.liveCooldownCount) {
            _syn.liveCooldownCount--;
        } else if (_syn.liveDrawing) {
            if (_syn.liveFailureCount > 3) {
                _syn.liveDrawing = false;
            } else {
                _syn.liveFailureCount++;
            }
        } else if (_syn.liveRefreshCount > 0) {
            _drawRefreshButtons('live');
            _syn.liveRefreshCount--;
        } else {
            _syn.liveRefreshCount = _syn.liveRefreshRate;
            _syn.liveCooldownCount = 2;
            _syn.liveDrawing = true;
            _syn.liveFailureCount = 0;
            _submitLive();
            _drawRefreshButtons('live');
        }
        if (_syn.nonliveCooldownCount) {
            _syn.nonliveCooldownCount--;
        } else if (_syn.nonliveDrawing) {
            if (_syn.nonliveFailureCount > 3) {
                _syn.nonliveDrawing = false;
            } else {
                _syn.nonliveFailureCount++;
            }
        } else if (_syn.nonliveRefreshCount > 0) {
            _drawRefreshButtons('nonlive');
            _syn.nonliveRefreshCount--;
        } else {
            _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
            _syn.nonliveCooldownCount = 2;
            _syn.nonliveDrawing = true;
            _syn.nonliveFailureCount = 0;
            _submitNonlive();
            _drawRefreshButtons('nonlive');
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('live');
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('nonlive');
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('live');
                        }, 200);
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('nonlive');
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onClick = function (event) {
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    }

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'od') {
                switch (atom[2]) {
                case 'fav':
                    if (count >= 4) {
                        if (atom[3] == 'add-tournament') {
                            var eventResults = _liveCache.getEventResultIdsByTournament(parseInt(atom[4]));
                            var nonLiveEvetnResults = _nonliveCache.getEventResultIdsByTournament(parseInt(atom[4]));
                            var allEventResults = [];
                            if (eventResults) {
                                allEventResults = eventResults;
                            }
                            if (nonLiveEvetnResults) {
                                allEventResults = allEventResults.concat(nonLiveEvetnResults);
                            }
                            $M('favourite').addRemoveFavourite(atom[3], allEventResults, atom[4]);
                        } else {
                            $M('favourite').addRemoveFavourite(atom[3], atom[4]);
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.liveVersion = 0;
            _syn.nonliveVersion = 0;
        } else if (_syn.liveDrawing || _syn.nonliveDrawing || _syn.liveCooldownCount || _syn.nonliveCooldownCount) {
            return;
        }
        _syn.liveRefreshCount = _syn.liveRefreshRate;
        _syn.liveCooldownCount = 2;
        _syn.liveDrawing = true;
        _syn.liveFailureCount = 0;
        _submitLive();
        _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
        _syn.nonliveCooldownCount = 2;
        _syn.nonliveDrawing = true;
        _syn.nonliveFailureCount = 0;
        _submitNonlive();
        _drawRefreshButtons();
    };
    this.refreshLive = function (clearAll) {
        if (!_syn.liveCooldownCount) {
            if (_syn.liveDrawing) {
                if (_syn.liveFailureCount > 3) {
                    _syn.liveDrawing = false;
                } else {
                    _syn.liveFailureCount++;
                }
            } else {
                if (clearAll) _syn.liveVersion = 0;
                _syn.liveRefreshCount = _syn.liveRefreshRate;
                _syn.liveCooldownCount = 2;
                _syn.liveDrawing = true;
                _syn.liveFailureCount = 0;
                _submitLive();
                _drawRefreshButtons('live');
            }
        }
    };
    this.refreshNonlive = function (clearAll) {
        if (!_syn.nonliveCooldownCount || clearAll) {
            if (_syn.nonliveDrawing && !clearAll) {
                if (_syn.nonliveFailureCount > 3) {
                    _syn.nonliveDrawing = false;
                } else {
                    _syn.nonliveFailureCount++;
                }
            } else {
                if (clearAll) _syn.nonliveVersion = 0;
                _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
                _syn.nonliveCooldownCount = 2;
                _syn.nonliveDrawing = true;
                _syn.nonliveFailureCount = 0;
                _submitNonlive();
                _drawRefreshButtons('nonlive');
            }
        }
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _liveCache.sort(sortType);
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_templateFavourite) {
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        if (!_templateLive) {
            _syn.liveWaitingTemplate = true;
            return;
        }
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        _populateNonliveSection(d);
        var div = document.getElementById('module-odds-display');
        if (div) {
            div.innerHTML = _templateLive['odds-display'].getText(d);
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
    }

    function _drawLive() {
        if (!_templateLive || !_templateFavourite) {
            _syn.liveWaitingTemplate = true;
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        var div = document.getElementById('odds-display-live');
        if (div) {
            div.innerHTML = d['odds-display-live'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _templateLive['odds-display'].getText(d);
            }
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
    }

    function _drawNonlive() {
        if (!_templateNonlive || !_templateFavourite) {
            _syn.nonliveWaitingTemplate = true;
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        _populateNonliveSection(d);
        var div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.innerHTML = d['odds-display-nonlive'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _templateNonlive['odds-display'].getText(d);
            }
        }
    }

    function _drawLoading() {
        if (_syn.liveVersion == 0 && _syn.nonliveVersion == 0 && _liveCache.isEmpty() && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_templateLive && _templateLive['loading']) {
                    text = _templateLive['loading'].getText();
                } else if (_templateNonlive && _templateNonlive['loading']) {
                    text = _templateNonlive['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _populateLiveSection(d) {
        $M('odds-display').clearRef();
        var template = _templateLive;
        var favTemplate = _templateFavourite;
        var cache = _liveCache;
        var favCache = $M('favourite').getCache();
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var marketGroupId = 0;
        var favourite;
        var showMarketGroups = $M('odds-display').getDisplaySetting('market-showing') == 2 ? true : false;
        var selectedOddId = $M('ticket').getOddIdOption();
        d['market-page'] = template['market-page-today'].getText();
        d['live-ext'] = template['live-ext'].getText();
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var marketGroup = tagEventResult[6];
            if (marketGroup && marketGroup[0] != 0 && !showMarketGroups) {
                continue;
            }
            var oddsFTime1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTime1X2] : null;
            var oddsFHalf1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalf1X2] : null;
            var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
            var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
            var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
            var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
            var oddsFTimeLS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeLS] : null;
            var rowCount = 0;
            if (oddsFTime1X2 && rowCount < oddsFTime1X2.length) {
                rowCount = oddsFTime1X2.length;
            }
            if (oddsFHalf1X2 && rowCount < oddsFHalf1X2.length) {
                rowCount = oddsFHalf1X2.length;
            }
            if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
                rowCount = oddsFTimeHDP.length;
            }
            if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
                rowCount = oddsFHalfHDP.length;
            }
            if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
                rowCount = oddsFTimeOU.length;
            }
            if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
                rowCount = oddsFHalfOU.length;
            }
            if (oddsFTimeLS && rowCount < oddsFTimeLS.length) {
                rowCount = oddsFTimeLS.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                var frozenOdds = eventResultExtra[8];
                var count = null;
                if (frozenOdds) {
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeHDP]) ? 0 : frozenOdds[_MarketDisplay.FTimeHDP];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalfHDP]) ? 0 : frozenOdds[_MarketDisplay.FHalfHDP];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeOU]) ? 0 : frozenOdds[_MarketDisplay.FTimeOU];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalfOU]) ? 0 : frozenOdds[_MarketDisplay.FHalfOU];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FTime1X2]) ? 0 : frozenOdds[_MarketDisplay.FTime1X2];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalf1X2]) ? 0 : frozenOdds[_MarketDisplay.FHalf1X2];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeLS]) ? 0 : frozenOdds[_MarketDisplay.FTimeLS];
                    rowCount = Math.max(rowCount, count);
                    rowCount = rowCount > 1 ? 1 : rowCount;
                }
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                if (favCache.hasTournament(tournament[0])) {
                    favourite = 'icon-live-tournament-remove';
                } else {
                    favourite = 'icon-live-tournament-add';
                }[0];
                marketGroupId = 0;
                d['icon-favourite-tournament'] = favTemplate[favourite].getText(d);
                rows.push(template['row-tournament'].getText(d));
                tournamentId = tournament
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasLiveVideo(eventId) ? template['icon-video'].getText(d) : null;
            d['ls-class'] = '';
            d['ls-tooltip'] = '';
            d['ls-id'] = 0;
            if (_mediaCache.hasLiveCenter(eventId)) {
                d['ls-class'] = 'ls-time-column';
                d['ls-tooltip'] = template['ls-tooltip'].getText();
                d['ls-id'] = d['event-id'];
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['home-score'] = eventResult[3];
            d['away-score'] = eventResult[4];
            d['score-separator'] = template['score-separator'].getText(d);
            d['draw'] = template['draw'].getText();
            d['vs'] = template['vs'].getText();
            d['score-class'] = cache.isScoreChanged(eventResultId) ? 'score-change' : '';
            var moreContent = '';
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 0)) {
                moreContent = $M('more').getContent(11);
            } else if ($M('more').isClosing(eventResultId, 0)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = showMarketGroups ? cache.getEventResultMoreOddsCount(eventResultId) : cache.getEventMoreOddsCount(eventResultId);
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            if (marketGroup && marketGroup[0]) {
                OddsUtility.populateMarketGroup(d, marketGroup);
                OddsUtility.populateMarketGroupTeams(d, marketGroup);
                if (marketGroupId != marketGroup[0]) {
                    marketGroupId = marketGroup[0];
                    rows.push(template['row-market-group'].getText(d));
                }
                d['icon-statistics'] = '';
                d['icon-video'] = '';
            } else {
                marketGroupId = 0;
            }
            if (favCache.hasEventResult(eventResultId) || favCache.hasTournament(tournamentId)) {
                favourite = 'icon-live-event-remove';
            } else {
                favourite = 'icon-live-event-add';
            }
            d['icon-favourite-event'] = favTemplate[favourite].getText(d);
            d['live-time'] = template['time-live'].getText(d);
            if (eventResultExtra) {
                var period = eventResultExtra[2];
                if (period > 0) {
                    if (period == 5) {
                        d['live-time'] = template['time-halftime'].getText(d);
                    } else {
                        d['live-time'] = OddsUtility.getLiveTime(period, cache.getLiveStartTime(eventResultId), eventResultExtra[3], eventResultExtra[4]);
                        var injuryTime = parseInt('' + eventResultExtra[7], 10);
                        if (injuryTime && injuryTime > 0) {
                            d['injuryTimeCount'] = injuryTime;
                            d['live-time'] += template['injury-time'].getText(d);
                        }
                    }
                }
            }
            var homeRedCards = '';
            var awayRedCards = '';
            if (eventResultExtra) {
                var redCardIndex;
                var redCardCount = eventResultExtra[5];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        homeRedCards += template['red-card'].getText(d);
                    }
                }
                redCardCount = eventResultExtra[6];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        awayRedCards += template['red-card'].getText(d);
                    }
                }
            }
            d['home-red-cards'] = homeRedCards;
            d['away-red-cards'] = awayRedCards;
            d['sub-row'] = '';
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                var has1X2 = false;
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['home-color-class'] = hdp > 0 ? 'Red' : 'Blue';
                d['away-color-class'] = hdp < 0 ? 'Red' : 'Blue';
                odds = oddsFTime1X2 ? oddsFTime1X2[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTime1X2);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTime1X2);
                }
                odds = oddsFHalf1X2 ? oddsFHalf1X2[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalf1X2);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalf1X2);
                }
                odds = oddsFTimeLS ? oddsFTimeLS[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeLS);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeLS);
                }
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeHDP);
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfHDP);
                }
                odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOU);
                }
                odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOU);
                }
                d['row-index'] = oddsRowIndex;
                var rowTemplateName;
                if (marketGroup && marketGroup[5]) {
                    rowTemplateName = 'row-event-yesno';
                    if (has1X2) {
                        rowTemplateName = 'row-event-yesno-1x2';
                    }
                } else if (!has1X2 && template['row-event-no1x2']) {
                    rowTemplateName = 'row-event-no1x2';
                } else {
                    rowTemplateName = 'row-event';
                }
                d['bg-color'] = (templateRowIndex & 1) ? '#FFDDCC' : '#FFDDCC';
                rows.push(template[rowTemplateName].getText(d));
                oddsRowIndex++;
                d['icon-statistics'] = null;
                d['icon-video'] = null;
                d['ls-class'] = '';
                d['ls-id'] = 0;
                d['ls-tooltip'] = '';
                d['home-score'] = null;
                d['away-score'] = null;
                d['score-separator'] = null;
                d['draw'] = null;
                d['vs'] = null;
                d['score-class'] = null;
                d['icon-more'] = null;
                d['live-time'] = null;
                d['home-red-cards'] = null;
                d['away-red-cards'] = null;
                d['original-home'] = null;
                d['original-away'] = null;
                d['home'] = null;
                d['away'] = null;
                d['tv-channel'] = null;
                d['sub-row'] = 'subrow';
                d['icon-favourite-event'] = null;
            }
            rows.push(moreContent);
            templateRowIndex++;
        }
        var ret = 0;
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['refresh-count'] = _syn.liveRefreshCount;
            d['refresh-button'] = _syn.liveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
            d['additional-class'] = _getAdditionalClass();
            d['table'] = template['table'].getText(d);
            d['odds-display-live'] = template['odds-display-live'].getText(d);
            ret = rows.length;
        } else if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
            _drawLoading();
            ret = 0;
        } else {
            d['odds-display-live'] = '';
            ret = 0;
        }
        return ret;
    }

    function _getAdditionalClass() {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        switch (parseInt(sportId)) {
        case 2:
            return _templateLive['basketball-additional-class'].getText();
        default:
            return '';
        }
    }

    function _populateDaylightType(d) {
        var daylightType = $M('odds-display').getDisplaySetting('daylight-type');
        if (_daylightPeriod) {
            $M('odds-display-setting').draw();
        }
    }

    function _populateNonliveSection(d) {
        $M('odds-display').clearRef();
        var template = _templateNonlive;
        var favTemplate = _templateFavourite;
        var cache = _nonliveCache;
        var favCache = $M('favourite').getCache();
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var moreContent = '';
        d['market-page'] = template['market-page-today'].getText();
        d['nonlive-ext'] = template['nonlive-ext'].getText();
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        var selectedOddId = $M('ticket').getOddIdOption();
        var sportId = $M('odds-display').getDisplaySetting('sport');
        var colSpan = _NonliveColSpan[sportId];
        if (!colSpan) colSpan = _NonliveColSpan[7];
        if (sportId == 1) {
            _populateDaylightType(d);
        }
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var oddsFTime1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTime1X2] : null;
            var oddsFHalf1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalf1X2] : null;
            var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
            var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
            var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
            var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
            var oddsML = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.ML] : null;
            var oddsFTimeOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOE] : null;
            var oddsFHalfOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOE] : null;
            var rowCount = 0;
            if (oddsFTime1X2 && rowCount < oddsFTime1X2.length) {
                rowCount = oddsFTime1X2.length;
            }
            if (oddsFHalf1X2 && rowCount < oddsFHalf1X2.length) {
                rowCount = oddsFHalf1X2.length;
            }
            if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
                rowCount = oddsFTimeHDP.length;
            }
            if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
                rowCount = oddsFHalfHDP.length;
            }
            if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
                rowCount = oddsFTimeOU.length;
            }
            if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
                rowCount = oddsFHalfOU.length;
            }
            if (oddsML && rowCount < oddsML.length) {
                rowCount = oddsML.length;
            }
            if (oddsFTimeOE && rowCount < oddsFTimeOE.length) {
                rowCount = oddsFTimeOE.length;
            }
            if (oddsFHalfOE && rowCount < oddsFHalfOE.length) {
                rowCount = oddsFHalfOE.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                rowCount = 1;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                if (favCache.hasTournament(tournamentId)) {
                    favourite = 'icon-nonlive-tournament-remove';
                } else {
                    favourite = 'icon-nonlive-tournament-add';
                }
                d['icon-favourite-tournament'] = favTemplate[favourite].getText(d);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = template['showtime-date-time'].getText(d);
            }
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? template['icon-video-nonlive'].getText(d) : '';
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['draw'] = template['draw'].getText();
            var moreContent = '';
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 1)) {
                moreContent = $M('more').getContent(colSpan);
            } else if ($M('more').isClosing(eventResultId, 1)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = cache.getEventMoreOddsCount(eventResultId);
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            d['sub-row'] = '';
            favourite = favCache.hasEventResult(eventResultId) || favCache.hasTournament(tournamentId) ? 'icon-nonlive-event-remove' : 'icon-nonlive-event-add';
            d['icon-favourite-event'] = favTemplate[favourite].getText(d);
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                var has1X2 = false;
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['home-color-class'] = hdp > 0 ? 'Red' : 'Blue';
                d['away-color-class'] = hdp < 0 ? 'Red' : 'Blue';
                odds = oddsFTime1X2 ? oddsFTime1X2[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTime1X2);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTime1X2);
                }
                odds = oddsFHalf1X2 ? oddsFHalf1X2[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalf1X2);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalf1X2);
                }
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeHDP);
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfHDP);
                }
                odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOU);
                }
                odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOU);
                }
                odds = oddsML ? oddsML[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.ML);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.ML);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.ML);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.ML);
                }
                odds = oddsFTimeOE ? oddsFTimeOE[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOE);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOE);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOE);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOE);
                }
                odds = oddsFHalfOE ? oddsFHalfOE[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOE);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOE);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOE);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOE);
                }
                d['row-index'] = oddsRowIndex;
                oddsRowIndex++;
                rows.push(template[(templateRowIndex & 1) ? 'row-event-alt' : 'row-event'].getText(d));
                d['icon-video'] = null;
                d['icon-statistics'] = null;
                d['showtime'] = null;
                d['live-time'] = null;
                d['home'] = null;
                d['away'] = null;
                d['draw'] = null;
                d['icon-more'] = null;
                d['sub-row'] = 'subrow';
                d['icon-favourite-event'] = null;
            }
            rows.push(moreContent);
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.nonliveRefreshCount;
        d['refresh-button'] = _syn.nonliveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        } else if (cache.isEmpty() && _syn.nonliveVersion == 0) {
            _drawLoading();
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        }
    }

    function _drawRefreshButtons(section) {
        if (!_templateLive) {
            _syn.livewaitingtemplate = true;
            return;
        }
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        if (section === undefined || section == 'live') {
            var a = document.getElementById('bu:od:refresh-live:button');
            if (a) {
                if (_syn.liveCooldownCount) {
                    a.innerHTML = _templateLive['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _templateLive['refresh'].getText();
                } else {
                    a.innerHTML = _templateLive['refresh-countdown'].getText({
                        'refresh-count': _syn.liveRefreshCount
                    });
                }
            }
        }
        if (section === undefined || section == 'nonlive') {
            a = document.getElementById('bu:od:refresh-nonlive:button');
            if (a) {
                if (_syn.nonliveCooldownCount) {
                    a.innerHTML = _templateNonlive['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _templateNonlive['refresh'].getText();
                } else {
                    a.innerHTML = _templateNonlive['refresh-countdown'].getText({
                        'refresh-count': _syn.nonliveRefreshCount
                    });
                }
            }
        }
    }
}

function __Module_TodaySingle(refreshRate, sortType) {
    var _MarketDisplay = {
        FTime1X2: 5,
        FHalf1X2: 8,
        FTimeHDP: 1,
        FHalfHDP: 7,
        FTimeOU: 3,
        FHalfOU: 9,
        FTimeOE: 2,
        ML: 11
    };
    var _TemplateNameLive = 'odds-display/today-single-live';
    var _TemplateNameNonlive = 'odds-display/today-single-nonlive';
    var _TemplateNameFavourite = 'left-column/favourite';
    var _self = this;
    var _templateLive = null;
    var _templateNonlive = null;
    var _templateFavourite = null;
    var _liveCache = new __Cache_Event(sortType);
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _daylightPeriod = 0;
    var _syn = {
        liveWaitingTemplate: false,
        liveDrawing: false,
        liveRefreshRate: refreshRate[0],
        liveRefreshCount: 0,
        liveCooldownCount: 0,
        liveFailureCount: 0,
        liveVersion: 0,
        nonliveWaitingTemplate: false,
        nonliveDrawing: false,
        nonliveRefreshRate: refreshRate[1],
        nonliveRefreshCount: 0,
        nonliveCooldownCount: 0,
        nonliveFailureCount: 0,
        nonliveVersion: 0,
        nonliveWaitToDraw: false,
        favouriteWaitingTemplate: false
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateNameLive);
        if (templateText) {
            _templateLive = TiLib.Template.createTemplates(templateText);
        }
        templateText = $P.getTemplate(_TemplateNameNonlive);
        if (templateText) {
            _templateNonlive = TiLib.Template.createTemplates(templateText);
        }
        templateText = $P.getTemplate(_TemplateNameFavourite);
        if (templateText) {
            _templateFavourite = TiLib.Template.createTemplates(templateText);
        }
        if (_templateNonlive || _templateLive || _templateFavourite) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateNameLive) {
            var templateText = $P.getTemplate(_TemplateNameLive);
            if (templateText) {
                _templateLive = TiLib.Template.createTemplates(templateText);
                if (_templateLive) {
                    if (_syn.liveWaitingTemplate) {
                        _syn.liveWaitingTemplate = false;
                        _drawLive();
                    }
                    if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
        if (name == _TemplateNameNonlive) {
            var templateText = $P.getTemplate(_TemplateNameNonlive);
            if (templateText) {
                _templateNonlive = TiLib.Template.createTemplates(templateText);
                if (_templateNonlive) {
                    if (_syn.nonliveWaitingTemplate) {
                        _syn.nonliveWaitingTemplate = false;
                        _drawNonlive();
                    }
                    if (_syn.nonliveVersion == 0 && _nonliveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
        if (name == _TemplateNameFavourite) {
            var templateText = $P.getTemplate(_TemplateNameFavourite);
            if (templateText) {
                _templateFavourite = TiLib.Template.createTemplates(templateText);
                if (_templateFavourite) {
                    if (_syn.favouriteWaitingTemplate) {
                        _syn.favouriteWaitingTemplate = false;
                        if (!_syn.liveDrawing && !_syn.nonliveDrawing) {
                            _drawLive();
                            _drawNonlive();
                        }
                    }
                }
            }
        }
    };
    this.onIdle = function (data) {
        var version = data[0];
        var frameIndex = data[1];
        if (frameIndex == 0) {
            if (_syn.liveVersion < version) {
                _syn.liveVersion = version;
            }
            _liveCache.clearAdjustIndicators();
            _drawLive();
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
            }
            _nonliveCache.clearAdjustIndicators();
            _drawNonlive();
            _syn.nonliveDrawing = false;
        }
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var frameIndex = data[1];
        var clearAll = data[2];
        var frameData = data[3];
        var mediaData = data[4];
        var daylightType = data[5];
        var favouriteData = data[6];
        var isChanged = false;
        if (frameIndex == 0) {
            if (_liveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.liveVersion < version) {
                _syn.liveVersion = version;
                if (_liveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (favouriteData) {
                $M('favourite').onUpdate(favouriteData);
            }
            if (isChanged) {
                _drawLive();
                if (_syn.nonliveWaitToDraw) {
                    _syn.nonliveWaitToDraw = false;
                    _drawNonlive();
                }
            }
            if (!isChanged) {
                _drawLive();
            }
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_nonliveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
                if (_nonliveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (favouriteData) {
                $M('favourite').onUpdate(favouriteData);
            }
            if (daylightType && daylightType.length >= 2) {
                _daylightPeriod = daylightType[1];
                $M('odds-display').setDisplaySetting('daylight-type-period', daylightType[1]);
                $M('odds-display').setDisplaySetting('daylight-type', daylightType[0]);
            }
            if (isChanged) {
                if (_syn.liveVersion <= 0 && _nonliveCache.isEmpty()) {
                    _syn.nonliveWaitToDraw = true;
                } else {
                    _drawNonlive();
                }
            }
            if (!isChanged) {
                _drawNonlive();
            }
            _syn.nonliveDrawing = false;
        }
    };

    function _submitLive() {
        var sb = [];
        sb.push('odds-display/today-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=0&v=');
        sb.push(_syn.liveVersion);
        sb.push($M('more').getMoreParam(true));
        return TiLib.Ajax.sendRequest('today-single-live', sb.join(''));
    }

    function _submitNonlive() {
        var sb = [];
        sb.push('odds-display/today-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=1&v=');
        sb.push(_syn.nonliveVersion);
        sb.push('&dl=');
        sb.push($M('odds-display').getDisplaySetting('daylight-type'));
        sb.push($M('more').getMoreParam(false));
        return TiLib.Ajax.sendRequest('today-single-nonlive', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.liveCooldownCount) {
            _syn.liveCooldownCount--;
        } else if (_syn.liveDrawing) {
            if (_syn.liveFailureCount > 3) {
                _syn.liveDrawing = false;
            } else {
                _syn.liveFailureCount++;
            }
        } else if (_syn.liveRefreshCount > 0) {
            _drawRefreshButtons('live');
            _syn.liveRefreshCount--;
        } else {
            _syn.liveRefreshCount = _syn.liveRefreshRate;
            _syn.liveCooldownCount = 2;
            _syn.liveDrawing = true;
            _syn.liveFailureCount = 0;
            _submitLive();
            _drawRefreshButtons('live');
        }
        if (_syn.nonliveCooldownCount) {
            _syn.nonliveCooldownCount--;
        } else if (_syn.nonliveDrawing) {
            if (_syn.nonliveFailureCount > 3) {
                _syn.nonliveDrawing = false;
            } else {
                _syn.nonliveFailureCount++;
            }
        } else if (_syn.nonliveRefreshCount > 0) {
            _drawRefreshButtons('nonlive');
            _syn.nonliveRefreshCount--;
        } else {
            _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
            _syn.nonliveCooldownCount = 2;
            _syn.nonliveDrawing = true;
            _syn.nonliveFailureCount = 0;
            _submitNonlive();
            _drawRefreshButtons('nonlive');
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('live');
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('nonlive');
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('live');
                        }, 200);
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('nonlive');
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onClick = function (event) {
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    }

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'od') {
                switch (atom[2]) {
                case 'fav':
                    if (count >= 4) {
                        if (atom[3] == 'add-tournament') {
                            var eventResults = _liveCache.getEventResultIdsByTournament(parseInt(atom[4]));
                            var nonLiveEvetnResults = _nonliveCache.getEventResultIdsByTournament(parseInt(atom[4]));
                            var allEventResults = [];
                            if (eventResults) {
                                allEventResults = eventResults;
                            }
                            if (nonLiveEvetnResults) {
                                allEventResults = allEventResults.concat(nonLiveEvetnResults);
                            }
                            $M('favourite').addRemoveFavourite(atom[3], allEventResults, atom[4]);
                        } else {
                            $M('favourite').addRemoveFavourite(atom[3], atom[4]);
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.liveVersion = 0;
            _syn.nonliveVersion = 0;
        } else if (_syn.liveDrawing || _syn.nonliveDrawing || _syn.liveCooldownCount || _syn.nonliveCooldownCount) {
            return;
        }
        _syn.liveRefreshCount = _syn.liveRefreshRate;
        _syn.liveCooldownCount = 2;
        _syn.liveDrawing = true;
        _syn.liveFailureCount = 0;
        _submitLive();
        _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
        _syn.nonliveCooldownCount = 2;
        _syn.nonliveDrawing = true;
        _syn.nonliveFailureCount = 0;
        _submitNonlive();
        _drawRefreshButtons();
    };
    this.refreshLive = function (clearAll) {
        if (!_syn.liveCooldownCount) {
            if (_syn.liveDrawing) {
                if (_syn.liveFailureCount > 3) {
                    _syn.liveDrawing = false;
                } else {
                    _syn.liveFailureCount++;
                }
            } else {
                if (clearAll) _syn.liveVersion = 0;
                _syn.liveRefreshCount = _syn.liveRefreshRate;
                _syn.liveCooldownCount = 2;
                _syn.liveDrawing = true;
                _syn.liveFailureCount = 0;
                _submitLive();
                _drawRefreshButtons('live');
            }
        }
    };
    this.refreshNonlive = function (clearAll) {
        if (!_syn.nonliveCooldownCount || clearAll) {
            if (_syn.nonliveDrawing && !clearAll) {
                if (_syn.nonliveFailureCount > 3) {
                    _syn.nonliveDrawing = false;
                } else {
                    _syn.nonliveFailureCount++;
                }
            } else {
                if (clearAll) _syn.nonliveVersion = 0;
                _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
                _syn.nonliveCooldownCount = 2;
                _syn.nonliveDrawing = true;
                _syn.nonliveFailureCount = 0;
                _submitNonlive();
                _drawRefreshButtons('nonlive');
            }
        }
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _liveCache.sort(sortType);
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_templateLive) {
            _syn.liveWaitingTemplate = true;
            return;
        }
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        if (!_templateFavourite) {
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        _populateNonliveSection(d);
        var div = document.getElementById('module-odds-display');
        if (div) {
            div.innerHTML = _templateLive['odds-display'].getText(d);
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
    }

    function _drawLive() {
        if (!_templateLive || !_templateFavourite) {
            _syn.liveWaitingTemplate = true;
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        var div = document.getElementById('odds-display-live');
        if (div) {
            div.innerHTML = d['odds-display-live'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _templateLive['odds-display'].getText(d);
            }
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
    }

    function _drawNonlive() {
        if (!_templateNonlive || !_templateFavourite) {
            _syn.nonliveWaitingTemplate = true;
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        _populateNonliveSection(d);
        var div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.innerHTML = d['odds-display-nonlive'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _templateNonlive['odds-display'].getText(d);
            }
        }
    }

    function _drawLoading() {
        if (_syn.liveVersion == 0 && _syn.nonliveVersion == 0 && _liveCache.isEmpty() && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_templateLive && _templateLive['loading']) {
                    text = _templateLive['loading'].getText();
                } else if (_templateNonlive && _templateNonlive['loading']) {
                    text = _templateNonlive['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _populateDaylightType(d) {
        var daylightType = $M('odds-display').getDisplaySetting('daylight-type');
        if (_daylightPeriod) {
            $M('odds-display-setting').draw();
        }
    }

    function _populateLiveSection(d) {
        $M('odds-display').clearRef();
        var template = _templateLive;
        var favTemplate = _templateFavourite;
        var cache = _liveCache;
        var favCache = $M('favourite').getCache();
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var marketGroupId = 0;
        var showMarketGroups = $M('odds-display').getDisplaySetting('market-showing') == 2 ? true : false;
        var selectedOddId = $M('ticket').getOddIdOption();
        d['market-page'] = _templateLive['market-page-today'].getText();
        d['live-ext'] = _templateLive['live-ext'].getText();
        var sportId = $M('odds-display').getDisplaySetting('sport');
        d['sport-id'] = sportId;
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var marketGroup = tagEventResult[6];
            if (marketGroup && marketGroup[0] != 0 && !showMarketGroups) {
                continue;
            }
            var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
            var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
            var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
            var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
            var rowCount = 0;
            if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
                rowCount = oddsFTimeHDP.length;
            }
            if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
                rowCount = oddsFHalfHDP.length;
            }
            if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
                rowCount = oddsFTimeOU.length;
            }
            if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
                rowCount = oddsFHalfOU.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                var frozenOdds = eventResultExtra[8];
                var count = null;
                if (frozenOdds) {
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeHDP]) ? 0 : frozenOdds[_MarketDisplay.FTimeHDP];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalfHDP]) ? 0 : frozenOdds[_MarketDisplay.FHalfHDP];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeOU]) ? 0 : frozenOdds[_MarketDisplay.FTimeOU];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalfOU]) ? 0 : frozenOdds[_MarketDisplay.FHalfOU];
                    rowCount = Math.max(rowCount, count);
                    rowCount = rowCount > 1 ? 1 : rowCount;
                }
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                marketGroupId = 0;
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                if (favCache.hasTournament(tournament[0])) {
                    favourite = 'icon-live-tournament-remove';
                } else {
                    favourite = 'icon-live-tournament-add';
                }
                d['icon-favourite-tournament'] = favTemplate[favourite].getText(d);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasLiveVideo(eventId) ? template['icon-video'].getText(d) : null;
            d['ls-class'] = '';
            d['ls-tooltip'] = '';
            d['ls-id'] = 0;
            if (_mediaCache.hasLiveCenter(eventId)) {
                d['ls-class'] = 'ls-time-column';
                d['ls-tooltip'] = template['ls-tooltip'].getText();
                d['ls-id'] = d['event-id'];
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['home-score'] = eventResult[3];
            d['away-score'] = eventResult[4];
            d['score-separator'] = template['score-separator'].getText(d);
            d['draw'] = template['draw'].getText();
            d['vs'] = template['vs'].getText();
            d['score-class'] = cache.isScoreChanged(eventResultId) ? 'score-change' : '';
            var moreContent = '';
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 0)) {
                moreContent = $M('more').getContent(16);
            } else if ($M('more').isClosing(eventResultId, 0)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = showMarketGroups ? cache.getEventResultMoreOddsCount(eventResultId) : cache.getEventMoreOddsCount(eventResultId);
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            if (marketGroup && marketGroup[0]) {
                OddsUtility.populateMarketGroup(d, marketGroup);
                OddsUtility.populateMarketGroupTeams(d, marketGroup);
                if (marketGroupId != marketGroup[0]) {
                    marketGroupId = marketGroup[0];
                    rows.push(template['row-market-group'].getText(d));
                }
                d['icon-statistics'] = '';
                d['icon-video'] = '';
            } else {
                marketGroupId = 0;
            }
            if (favCache.hasEventResult(eventResultId) || favCache.hasTournament(tournamentId)) {
                favourite = 'icon-live-event-remove';
            } else {
                favourite = 'icon-live-event-add';
            }
            d['icon-favourite-event'] = favTemplate[favourite].getText(d);
            d['live-time'] = template['time-live'].getText(d);
            if (eventResultExtra) {
                var period = eventResultExtra[2];
                if (period > 0) {
                    if (period == 5) {
                        d['live-time'] = template['time-halftime'].getText(d);
                    } else {
                        d['live-time'] = OddsUtility.getLiveTime(period, cache.getLiveStartTime(eventResultId), eventResultExtra[3], eventResultExtra[4]);
                        var injuryTime = parseInt('' + eventResultExtra[7], 10);
                        if (injuryTime && injuryTime > 0) {
                            d['injuryTimeCount'] = injuryTime;
                            d['live-time'] += template['injury-time'].getText(d);
                        }
                    }
                }
            }
            var homeRedCards = '';
            var awayRedCards = '';
            if (eventResultExtra) {
                var redCardIndex;
                var redCardCount = eventResultExtra[5];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        homeRedCards += template['red-card'].getText(d);
                    }
                }
                redCardCount = eventResultExtra[6];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        awayRedCards += template['red-card'].getText(d);
                    }
                }
            }
            d['home-red-cards'] = homeRedCards;
            d['away-red-cards'] = awayRedCards;
            d['sub-row'] = '';
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['home-color-class'] = hdp > 0 ? 'Red' : 'Blue';
                d['away-color-class'] = hdp < 0 ? 'Red' : 'Blue';
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeHDP);
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfHDP);
                }
                odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOU);
                }
                odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOU);
                }
                d['row-index'] = oddsRowIndex;
                var rowTemplateName = 'row-event';
                if (marketGroup && marketGroup[4] && marketGroup[5] == 1) {
                    rowTemplateName = 'row-event-yesno';
                }
                d['bg-color'] = (templateRowIndex & 1) ? '#FFDDCC' : '#FFDDCC';
                rows.push(template[rowTemplateName].getText(d));
                oddsRowIndex++;
                d['icon-statistics'] = null;
                d['icon-video'] = null;
                d['ls-class'] = '';
                d['ls-id'] = 0;
                d['ls-tooltip'] = '';
                d['home-score'] = null;
                d['away-score'] = null;
                d['score-separator'] = null;
                d['draw'] = null;
                d['vs'] = null;
                d['score-class'] = null;
                d['icon-more'] = null;
                d['live-time'] = null;
                d['home-red-cards'] = null;
                d['away-red-cards'] = null;
                d['original-home'] = null;
                d['original-away'] = null;
                d['home'] = null;
                d['away'] = null;
                d['tv-channel'] = null;
                d['sub-row'] = 'subrow';
                d['icon-favourite-event'] = null;
            }
            rows.push(moreContent);
            templateRowIndex++;
        }
        var ret = 0;
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['refresh-count'] = _syn.liveRefreshCount;
            d['refresh-button'] = _syn.liveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
            d['additional-class'] = _getAdditionalClass();
            d['table'] = template['table'].getText(d);
            d['odds-display-live'] = template['odds-display-live'].getText(d);
            ret = rows.length;
        } else if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
            _drawLoading();
            ret = 0;
        } else {
            d['odds-display-live'] = '';
            ret = 0;
        }
        return ret;
    }

    function _populateNonliveSection(d) {
        $M('odds-display').clearRef();
        var template = _templateNonlive;
        var favTemplate = _templateFavourite;
        var cache = _nonliveCache;
        var favCache = $M('favourite').getCache();
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var selectedOddId = $M('ticket').getOddIdOption();
        d['market-page'] = template['market-page-today'].getText();
        d['nonlive-ext'] = template['nonlive-ext'].getText();
        var sportId = $M('odds-display').getDisplaySetting('sport');
        d['sport-id'] = sportId;
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        if (sportId == 1) _populateDaylightType(d);
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
            var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
            var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
            var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
            var rowCount = 0;
            if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
                rowCount = oddsFTimeHDP.length;
            }
            if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
                rowCount = oddsFHalfHDP.length;
            }
            if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
                rowCount = oddsFTimeOU.length;
            }
            if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
                rowCount = oddsFHalfOU.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                rowCount = 1;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                if (favCache.hasTournament(tournamentId)) {
                    favourite = 'icon-nonlive-tournament-remove';
                } else {
                    favourite = 'icon-nonlive-tournament-add';
                }
                d['icon-favourite-tournament'] = favTemplate[favourite].getText(d);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = template['showtime-date-time'].getText(d);
            }
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? template['icon-video-nonlive'].getText(d) : '';
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['draw'] = template['draw'].getText();
            var moreContent = '';
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 1)) {
                moreContent = $M('more').getContent(16);
            } else if ($M('more').isClosing(eventResultId, 1)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = cache.getEventMoreOddsCount(eventResultId);
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            d['sub-row'] = '';
            favourite = favCache.hasEventResult(eventResultId) || favCache.hasTournament(tournamentId) ? 'icon-nonlive-event-remove' : 'icon-nonlive-event-add';
            d['icon-favourite-event'] = favTemplate[favourite].getText(d);
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['home-color-class'] = hdp > 0 ? 'Red' : 'Blue';
                d['away-color-class'] = hdp < 0 ? 'Red' : 'Blue';
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeHDP);
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfHDP);
                }
                odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOU);
                }
                odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOU);
                }
                d['row-index'] = oddsRowIndex;
                oddsRowIndex++;
                rows.push(template[(templateRowIndex & 1) ? 'row-event-alt' : 'row-event'].getText(d));
                d['icon-video'] = null;
                d['icon-statistics'] = null;
                d['showtime'] = null;
                d['live-time'] = null;
                d['home'] = null;
                d['away'] = null;
                d['draw'] = null;
                d['icon-more'] = null;
                d['sub-row'] = 'subrow';
                d['icon-favourite-event'] = null;
            }
            rows.push(moreContent);
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.nonliveRefreshCount;
        d['refresh-button'] = _syn.nonliveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        } else if (cache.isEmpty() && _syn.nonliveVersion == 0) {
            _drawLoading();
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        }
    }

    function _getAdditionalClass() {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        switch (parseInt(sportId)) {
        case 2:
            return _templateLive['basketball-additional-class'].getText();
        default:
            return '';
        }
    }

    function _drawRefreshButtons(section) {
        if (!_templateLive) {
            _syn.waitingTemplate = true;
            return;
        }
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        if (section === undefined || section == 'live') {
            var a = document.getElementById('bu:od:refresh-live:button');
            if (a) {
                if (_syn.liveCooldownCount) {
                    a.innerHTML = _templateLive['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _templateLive['refresh'].getText();
                } else {
                    a.innerHTML = _templateLive['refresh-countdown'].getText({
                        'refresh-count': _syn.liveRefreshCount
                    });
                }
            }
        }
        if (section === undefined || section == 'nonlive') {
            a = document.getElementById('bu:od:refresh-nonlive:button');
            if (a) {
                if (_syn.nonliveCooldownCount) {
                    a.innerHTML = _templateNonlive['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _templateNonlive['refresh'].getText();
                } else {
                    a.innerHTML = _templateNonlive['refresh-countdown'].getText({
                        'refresh-count': _syn.nonliveRefreshCount
                    });
                }
            }
        }
    }
}

function __Module_EarlyMarketDouble(refreshRate, sortType) {
    var _MarketDisplay = {
        FTime1X2: 5,
        FHalf1X2: 8,
        FTimeHDP: 1,
        FHalfHDP: 7,
        FTimeOU: 3,
        FHalfOU: 9,
        FTimeOE: 2,
        FHalfOE: 12,
        ML: 11,
        FTimeLS: 16
    };
    var _SportNameNonlive = {
        1: 'soccer',
        2: 'basketball',
        3: 'football',
        7: 'motor',
        9: 'baseball',
        13: 'boxing',
        14: 'cricket',
        17: 'handball',
        28: 'winter',
        31: 'boxing'
    };
    var _NonliveColSpan = {
        1: 11,
        2: 10,
        3: 10,
        7: 8,
        9: 10,
        13: 7,
        14: 7,
        17: 7,
        28: 6,
        31: 7
    };
    var _TemplateNameNonlive = 'odds-display/today-double-nonlive';
    var _self = this;
    var _templateNonlive = null;
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _eventDateList = null;
    var _syn = {
        nonliveWaitingTemplate: false,
        nonliveDrawing: false,
        nonliveRefreshRate: refreshRate,
        nonliveRefreshCount: 0,
        nonliveCooldownCount: 0,
        nonliveFailureCount: 0,
        nonliveVersion: 0
    };
    this.initiate = function () {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        var extentNonlive = _SportNameNonlive[sportId];
        if (!extentNonlive) extentNonlive = 'motor';
        templateText = $P.getTemplate(_TemplateNameNonlive + '-' + extentNonlive);
        if (templateText) {
            _templateNonlive = TiLib.Template.createTemplates(templateText);
        }
        if (_templateNonlive) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        var extentNonlive = _SportNameNonlive[sportId];
        if (!extentNonlive) extentNonlive = 'motor';
        if (name == _TemplateNameNonlive + '-' + extentNonlive) {
            var templateText = $P.getTemplate(_TemplateNameNonlive + '-' + extentNonlive);
            if (templateText) {
                _templateNonlive = TiLib.Template.createTemplates(templateText);
                if (_templateNonlive) {
                    if (_syn.nonliveWaitingTemplate) {
                        _syn.nonliveWaitingTemplate = false;
                        _drawNonlive();
                    }
                    if (_syn.nonliveVersion == 0 && _nonliveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
    };
    this.onIdle = function (data) {
        var version = data[0];
        var eventDateList = data[1];
        if (eventDateList) {
            _eventDateList = eventDateList;
        }
        if (_syn.nonliveVersion < version) {
            _syn.nonliveVersion = version;
        }
        if (_nonliveCache.clearAdjustIndicators()) {
            _drawNonlive();
        }
        _syn.nonliveDrawing = false;
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var clearAll = data[1];
        var frameData = data[2];
        var mediaData = data[3];
        var eventDateList = data[4];
        var isChanged = false;
        if (_nonliveCache.clearAdjustIndicators()) {
            isChanged = true;
        }
        if (clearAll || _syn.nonliveVersion < version) {
            _syn.nonliveVersion = version;
            if (_nonliveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                isChanged = true;
            }
        }
        if (_mediaCache.update(mediaData)) {
            isChanged = true;
        }
        if (eventDateList) {
            _eventDateList = eventDateList;
        }
        if (isChanged) {
            _drawNonlive();
        }
        _syn.nonliveDrawing = false;
    };

    function _submitNonlive() {
        var sb = [];
        sb.push('odds-display/early-market-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&v=');
        sb.push(_syn.nonliveVersion);
        sb.push($M('more').getMoreParam(false));
        return TiLib.Ajax.sendRequest('earlymarket-double', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.nonliveCooldownCount) {
            _syn.nonliveCooldownCount--;
        } else if (_syn.nonliveDrawing) {
            if (_syn.nonliveFailureCount > 3) {
                _syn.nonliveDrawing = false;
            } else {
                _syn.nonliveFailureCount++;
            }
        } else if (_syn.nonliveRefreshCount > 0) {
            _drawRefreshButtons();
            _syn.nonliveRefreshCount--;
        } else {
            _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
            _syn.nonliveCooldownCount = 2;
            _syn.nonliveDrawing = true;
            _syn.nonliveFailureCount = 0;
            _submitNonlive();
            _drawRefreshButtons();
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-nonlive:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons();
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-nonlive:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons();
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.nonliveVersion = 0;
        } else if (_syn.nonliveDrawing || _syn.nonliveCooldownCount) {
            return;
        }
        _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
        _syn.nonliveCooldownCount = 2;
        _syn.nonliveDrawing = true;
        _syn.nonliveFailureCount = 0;
        _submitNonlive();
        _drawRefreshButtons();
    };
    this.refreshNonlive = function (clearAll) {
        if (!_syn.nonliveCooldownCount) {
            if (_syn.nonliveDrawing) {
                if (_syn.nonliveFailureCount > 3) {
                    _syn.nonliveDrawing = false;
                } else {
                    _syn.nonliveFailureCount++;
                }
            } else {
                if (clearAll) _syn.nonliveVersion = 0;
                _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
                _syn.nonliveCooldownCount = 2;
                _syn.nonliveDrawing = true;
                _syn.nonliveFailureCount = 0;
                _submitNonlive();
                _drawRefreshButtons('nonlive');
            }
        }
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        var d = {};
        _populateNonliveSection(d);
        var div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.innerHTML = d['odds-display-nonlive'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _templateNonlive['odds-display'].getText(d);
            }
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            div.parentNode.removeChild(div);
        }
    }

    function _drawNonlive() {
        _draw();
    }

    function _drawLoading() {
        if (_syn.nonliveVersion == 0 && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_templateNonlive && _templateNonlive['loading']) {
                    text = _templateNonlive['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _populateEMHeader(d) {
        $M('odds-display').clearRef();
        var template = _templateNonlive;
        var selectedDate = $M('odds-display').getDisplaySetting('event-date') - 1;
        if (!_eventDateList) {
            return;
        }
        for (var i = 1; i <= 8; i++) {
            d['event-date-text'] = _eventDateList[i - 1];
            d['em-' + i] = template['event-date'].getText(d);
            if (selectedDate == i) {
                d['em-selected'] = d['em-' + i];
            }
        }
        d['em-header'] = template['em-header'].getText(d);
    }

    function _populateNonliveSection(d) {
        var template = _templateNonlive;
        var cache = _nonliveCache;
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var selectedOddId = $M('ticket').getOddIdOption();
        d['market-page'] = template['market-page-early-market'].getText();
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        _populateEMHeader(d);
        var sportId = $M('odds-display').getDisplaySetting('sport');
        var colSpan = _NonliveColSpan[sportId];
        if (!colSpan) colSpan = _NonliveColSpan[7];
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var oddsFTime1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTime1X2] : null;
            var oddsFHalf1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalf1X2] : null;
            var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
            var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
            var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
            var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
            var oddsFTimeOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOE] : null;
            var oddsFHalfOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOE] : null;
            var oddsML = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.ML] : null;
            var rowCount = 0;
            if (oddsFTime1X2 && rowCount < oddsFTime1X2.length) {
                rowCount = oddsFTime1X2.length;
            }
            if (oddsFHalf1X2 && rowCount < oddsFHalf1X2.length) {
                rowCount = oddsFHalf1X2.length;
            }
            if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
                rowCount = oddsFTimeHDP.length;
            }
            if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
                rowCount = oddsFHalfHDP.length;
            }
            if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
                rowCount = oddsFTimeOU.length;
            }
            if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
                rowCount = oddsFHalfOU.length;
            }
            if (oddsFTimeOE && rowCount < oddsFTimeOE.length) {
                rowCount = oddsFTimeOE.length;
            }
            if (oddsFHalfOE && rowCount < oddsFHalfOE.length) {
                rowCount = oddsFHalfOE.length;
            }
            if (oddsML && rowCount < oddsML.length) {
                rowCount = oddsML.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                rowCount = 1;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = template['showtime-date-time'].getText(d);
            }
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? template['icon-video-nonlive'].getText(d) : '';
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['draw'] = template['draw'].getText();
            var moreContent = ''
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 1)) {
                moreContent = $M('more').getContent(colSpan);
            } else if ($M('more').isClosing(eventResultId, 1)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = cache.getEventMoreOddsCount(eventResultId);
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            d['sub-row'] = '';
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                var has1X2 = false;
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['home-color-class'] = hdp > 0 ? 'Red' : 'Blue';
                d['away-color-class'] = hdp < 0 ? 'Red' : 'Blue';
                odds = oddsFTime1X2 ? oddsFTime1X2[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTime1X2);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTime1X2);
                }
                odds = oddsFHalf1X2 ? oddsFHalf1X2[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalf1X2);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalf1X2);
                }
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeHDP);
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfHDP);
                }
                odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOU);
                }
                odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOU);
                }
                odds = oddsFTimeOE ? oddsFTimeOE[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOE);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOE);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOE);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOE);
                }
                odds = oddsFHalfOE ? oddsFHalfOE[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOE);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOE);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOE);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOE);
                }
                odds = oddsML ? oddsML[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.ML);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.ML);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.ML);
                }
                d['row-index'] = oddsRowIndex;
                oddsRowIndex++;
                rows.push(template[(templateRowIndex & 1) ? 'row-event-alt' : 'row-event'].getText(d));
                d['icon-video'] = null;
                d['icon-statistics'] = null;
                d['showtime'] = null;
                d['live-time'] = null;
                d['home'] = null;
                d['away'] = null;
                d['draw'] = null;
                d['icon-more'] = null;
                d['sub-row'] = 'subrow';
            }
            rows.push(moreContent);
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.nonliveRefreshCount;
        d['refresh-button'] = _syn.nonliveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        } else if (cache.isEmpty() && _syn.nonliveVersion == 0) {
            _drawLoading();
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        }
    }

    function _drawRefreshButtons() {
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        var a = document.getElementById('bu:od:refresh-nonlive:button');
        if (a) {
            if (_syn.nonliveCooldownCount) {
                a.innerHTML = _templateNonlive['refresh-refreshing'].getText();
            } else if (a.isHover) {
                a.innerHTML = _templateNonlive['refresh'].getText();
            } else {
                a.innerHTML = _templateNonlive['refresh-countdown'].getText({
                    'refresh-count': _syn.nonliveRefreshCount
                });
            }
        }
    }
}

function __Module_EarlyMarketSingle(refreshRate, sortType) {
    var _MarketDisplay = {
        FTime1X2: 5,
        FHalf1X2: 8,
        FTimeHDP: 1,
        FHalfHDP: 7,
        FTimeOU: 3,
        FHalfOU: 9,
        FTimeOE: 2,
        FHalfOE: 12,
        ML: 11,
        FTimeLS: 16
    };
    var _TemplateNameNonlive = 'odds-display/today-single-nonlive';
    var _self = this;
    var _templateNonlive = null;
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _eventDateList = null;
    var _syn = {
        nonliveWaitingTemplate: false,
        nonliveDrawing: false,
        nonliveRefreshRate: refreshRate,
        nonliveRefreshCount: 0,
        nonliveCooldownCount: 0,
        nonliveFailureCount: 0,
        nonliveVersion: 0
    };
    this.initiate = function () {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        templateText = $P.getTemplate(_TemplateNameNonlive);
        if (templateText) {
            _templateNonlive = TiLib.Template.createTemplates(templateText);
        }
        if (_templateNonlive) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        if (name == _TemplateNameNonlive) {
            var templateText = $P.getTemplate(_TemplateNameNonlive);
            if (templateText) {
                _templateNonlive = TiLib.Template.createTemplates(templateText);
                if (_templateNonlive) {
                    if (_syn.nonliveWaitingTemplate) {
                        _syn.nonliveWaitingTemplate = false;
                        _drawNonlive();
                    }
                    if (_syn.nonliveVersion == 0 && _nonliveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
    };
    this.onIdle = function (data) {
        var version = data[0];
        var eventDateList = data[1];
        if (eventDateList) {
            _eventDateList = eventDateList;
        }
        if (_syn.nonliveVersion < version) {
            _syn.nonliveVersion = version;
        }
        if (_nonliveCache.clearAdjustIndicators()) {
            _drawNonlive();
        }
        _syn.nonliveDrawing = false;
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var clearAll = data[1];
        var frameData = data[2];
        var mediaData = data[3];
        var eventDateList = data[4];
        var isChanged = false;
        if (_nonliveCache.clearAdjustIndicators()) {
            isChanged = true;
        }
        if (clearAll || _syn.nonliveVersion < version) {
            _syn.nonliveVersion = version;
            if (_nonliveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                isChanged = true;
            }
        }
        if (_mediaCache.update(mediaData)) {
            isChanged = true;
        }
        if (eventDateList) {
            if (!_eventDateList) isChanged = true;
            _eventDateList = eventDateList;
        }
        if (isChanged) {
            _drawNonlive();
        }
        _syn.nonliveDrawing = false;
    };

    function _submitNonlive() {
        var sb = [];
        sb.push('odds-display/early-market-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&v=');
        sb.push(_syn.nonliveVersion);
        sb.push($M('more').getMoreParam(false));
        return TiLib.Ajax.sendRequest('earlymarket-single', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.nonliveCooldownCount) {
            _syn.nonliveCooldownCount--;
        } else if (_syn.nonliveDrawing) {
            if (_syn.nonliveFailureCount > 3) {
                _syn.nonliveDrawing = false;
            } else {
                _syn.nonliveFailureCount++;
            }
        } else if (_syn.nonliveRefreshCount > 0) {
            _drawRefreshButtons();
            _syn.nonliveRefreshCount--;
        } else {
            _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
            _syn.nonliveCooldownCount = 2;
            _syn.nonliveDrawing = true;
            _syn.nonliveFailureCount = 0;
            _submitNonlive();
            _drawRefreshButtons();
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-nonlive:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons();
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-nonlive:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons();
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.nonliveVersion = 0;
        } else if (_syn.nonliveDrawing || _syn.nonliveCooldownCount) {
            return;
        }
        _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
        _syn.nonliveCooldownCount = 2;
        _syn.nonliveDrawing = true;
        _syn.nonliveFailureCount = 0;
        _submitNonlive();
        _drawRefreshButtons();
    };
    this.refreshNonlive = function (clearAll) {
        if (!_syn.nonliveCooldownCount) {
            if (_syn.nonliveDrawing) {
                if (_syn.nonliveFailureCount > 3) {
                    _syn.nonliveDrawing = false;
                } else {
                    _syn.nonliveFailureCount++;
                }
            } else {
                if (clearAll) _syn.nonliveVersion = 0;
                _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
                _syn.nonliveCooldownCount = 2;
                _syn.nonliveDrawing = true;
                _syn.nonliveFailureCount = 0;
                _submitNonlive();
                _drawRefreshButtons('nonlive');
            }
        }
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        var d = {};
        _populateNonliveSection(d);
        var div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.innerHTML = d['odds-display-nonlive'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _templateNonlive['odds-display'].getText(d);
            }
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            div.parentNode.removeChild(div);
        }
    }

    function _drawNonlive() {
        _draw();
    }

    function _drawLoading() {
        if (_syn.nonliveVersion == 0 && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_templateNonlive && _templateNonlive['loading']) {
                    text = _templateNonlive['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _populateEMHeader(d) {
        var template = _templateNonlive;
        var selectedDate = $M('odds-display').getDisplaySetting('event-date') - 1;
        if (!_eventDateList) {
            return;
        }
        for (var i = 1; i <= 8; i++) {
            d['event-date-text'] = _eventDateList[i - 1];
            d['em-' + i] = template['event-date'].getText(d);
            if (selectedDate == i) {
                d['em-selected'] = d['em-' + i];
            }
        }
        d['em-header'] = _templateNonlive['em-header'].getText(d);
    }

    function _populateNonliveSection(d) {
        $M('odds-display').clearRef();
        var template = _templateNonlive;
        var cache = _nonliveCache;
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var selectedOddId = $M('ticket').getOddIdOption();
        d['market-page'] = template['market-page-early-market'].getText();
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        _populateEMHeader(d);
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
            var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
            var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
            var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
            var rowCount = 0;
            if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
                rowCount = oddsFTimeHDP.length;
            }
            if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
                rowCount = oddsFHalfHDP.length;
            }
            if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
                rowCount = oddsFTimeOU.length;
            }
            if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
                rowCount = oddsFHalfOU.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                rowCount = 1;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = template['showtime-date-time'].getText(d);
            }
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? template['icon-video-nonlive'].getText(d) : '';
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['draw'] = template['draw'].getText();
            var moreContent = '';
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 1)) {
                moreContent = $M('more').getContent(16);
            } else if ($M('more').isClosing(eventResultId, 1)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = cache.getEventMoreOddsCount(eventResultId);
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            d['sub-row'] = '';
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                var has1X2 = false;
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['home-color-class'] = hdp > 0 ? 'Red' : 'Blue';
                d['away-color-class'] = hdp < 0 ? 'Red' : 'Blue';
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeHDP);
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfHDP);
                }
                odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOU);
                }
                odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOU);
                }
                d['row-index'] = oddsRowIndex;
                oddsRowIndex++;
                rows.push(template[(templateRowIndex & 1) ? 'row-event-alt' : 'row-event'].getText(d));
                d['icon-video'] = null;
                d['icon-statistics'] = null;
                d['showtime'] = null;
                d['live-time'] = null;
                d['home'] = null;
                d['away'] = null;
                d['draw'] = null;
                d['icon-more'] = null;
                d['sub-row'] = 'subrow';
            }
            rows.push(moreContent);
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.nonliveRefreshCount;
        d['refresh-button'] = _syn.nonliveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        } else if (cache.isEmpty() && _syn.nonliveVersion == 0) {
            _drawLoading();
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        }
    }

    function _drawRefreshButtons() {
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        var a = document.getElementById('bu:od:refresh-nonlive:button');
        if (a) {
            if (_syn.nonliveCooldownCount) {
                a.innerHTML = _templateNonlive['refresh-refreshing'].getText();
            } else if (a.isHover) {
                a.innerHTML = _templateNonlive['refresh'].getText();
            } else {
                a.innerHTML = _templateNonlive['refresh-countdown'].getText({
                    'refresh-count': _syn.nonliveRefreshCount
                });
            }
        }
    }
}

function __Module_MixParlay(oddsDisplayInitialParams, sortType) {
    var _MarketDisplay = {
        FTime1X2: 5,
        FHalf1X2: 8,
        FTimeHDP: 1,
        FHalfHDP: 7,
        FTimeOU: 3,
        FHalfOU: 9,
        FTimeOE: 2,
        FHalfOE: 12,
        ML: 11
    };
    var _TemplateName = 'odds-display/mixparlay';
    var _self = this;
    var _dataParam = null;
    var _template = null;
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _maxPayout = oddsDisplayInitialParams['maxPayout'];
    var _halfMaxPayout = oddsDisplayInitialParams['halfMaxPayout'];
    var _selectedOddDictionary = $M('ticket').getOddsIdDictionary();
    var _sports = [];
    var _dates = [];
    var _syn = {
        waitingTemplate: false,
        drawing: false,
        refreshRate: oddsDisplayInitialParams['refreshRate'],
        refreshCount: 0,
        cooldownCount: 0,
        failureCount: 0,
        version: 0
    };
    this.initiate = function () {
        _dataParam = TiLib.Parameter.createParameter(['sport', 'date'], [$M('odds-display').getDisplaySetting('sport'), 0])
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        if (_template) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_template) {
                    if (_syn.waitingTemplate) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                    if (_syn.liveVersion == 0 && _nonliveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
    };
    this.onIdle = function (version) {
        if (_syn.version < version) {
            _syn.version = version;
        }
        _drawOptions();
        if (_nonliveCache.clearAdjustIndicators()) {
            _drawOddsTable();
        }
        _syn.drawing = false;
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var clearAll = data[1];
        _sports = data[2];
        _dates = data[3];
        var cacheData = data[4];
        var mediaData = data[5];
        var payout = data[6];
        var isOddsChanged = false;
        if (payout) {
            _maxPayout = payout[0];
            _halfMaxPayout = payout[1];
        }
        _drawOptions();
        if (_nonliveCache.clearAdjustIndicators()) {
            isOddsChanged = true;
        }
        if (clearAll || _syn.version < version) {
            _syn.version = version;
            _nonliveCache.update(clearAll, cacheData);
            isOddsChanged = true;
        }
        if (_mediaCache.update(mediaData)) {
            isOddsChanged = true;
        }
        if (isOddsChanged) {
            _drawOddsTable();
        }
        _syn.drawing = false;
    };

    function _submit() {
        var sb = [];
        sb.push('odds-display/mixparlay-data.aspx?param=');
        sb.push(_dataParam.getJoinedValues());
        sb.push('&fi=0&v=');
        sb.push(_syn.version);
        sb.push('&token=');
        sb.push($M('odds-display').getDisplaySetting('token'));
        sb.push($M('more').getMoreParam(false));
        return TiLib.Ajax.sendRequest('mixparlay', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.cooldownCount) {
            _syn.cooldownCount--;
        } else if (_syn.drawing) {
            if (_syn.failureCount > 3) {
                _syn.drawing = false;
            } else {
                _syn.failureCount++;
            }
        } else if (_syn.refreshCount > 0) {
            _drawRefreshButtons();
            _syn.refreshCount--;
        } else {
            _syn.refreshCount = _syn.refreshRate;
            _syn.cooldownCount = 2;
            _syn.drawing = true;
            _syn.failureCount = 0;
            _submit();
            _drawRefreshButtons();
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons();
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons();
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.version = 0;
        } else if (_syn.drawing || _syn.cooldownCount) {
            return;
        }
        _syn.refreshCount = _syn.refreshRate;
        _syn.cooldownCount = 2;
        _syn.drawing = true;
        _syn.failureCount = 0;
        _submit();
        _drawRefreshButtons('nonlive');
    };
    this.refreshNonlive = function (clearAll) {
        if (!_syn.cooldownCount) {
            if (_syn.drawing) {
                if (_syn.failureCount > 3) {
                    _syn.drawing = false;
                } else {
                    _syn.failureCount++;
                }
            } else {
                if (clearAll) _syn.version = 0;
                _syn.refreshCount = _syn.refreshRate;
                _syn.cooldownCount = 2;
                _syn.drawing = true;
                _syn.failureCount = 0;
                _submit();
                _drawRefreshButtons('nonlive');
            }
        }
    };
    this.onClick = function (event) {
        if (!event) event = window.event;
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    };

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'od') {
                switch (atom[2]) {
                case 'sport':
                    if (count >= 4) {
                        $M('more').clearMoreBlockInfo();
                        _dataParam.setValue('sport', atom[3]);
                        _dataParam.setValue('date', 0);
                        _self.refresh(true);
                    }
                    return false;
                case 'date':
                    if (count >= 4) {
                        $M('odds-display').setDisplaySetting('limited-rows', 50);
                        $M('more').clearMoreBlockInfo();
                        _dataParam.setValue('date', atom[3]);
                        _self.refresh(true);
                    }
                    return false;
                case 'select-tournament':
                    _dataParam.setValue('date', 8);
                    if (count >= 4) {
                        $M('select-tournament').open(1, _dataParam.getValue('sport'), _dataParam.getValue('date'));
                    }
                    return false;
                }
            }
        }
        return true;
    }

    function _openTicket(oddsId, option, price, hdpType) {
        var form = document.getElementById("ticketForm");
        if (form) {
            form.id.value = oddsId;
            form.odds.value = price;
            if (form.hidRefreshOdds) {
                form.hidRefreshOdds.value = '';
            }
            if (form.hidAuto) {
                form.hidAuto.value = '';
            }
            if (option) {
                form.op.value = option;
            }
            if (form.hdpType) {
                form.hdpType.value = hdpType ? hdpType : 0;
            }
            form.submit();
        }
    }
    this.selectTournaments = function () {
        var sb = [];
        sb.push('select-tournament.aspx?name=mixparlay&sport=');
        sb.push(_dataParam.getValue('sport'));
        document.location.replace(sb.join(''));
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var d = {};
        _populateOptions(d);
        _populateOddsTable(d);
        var div = document.getElementById('module-odds-display');
        if (div && _syn.version > 0) {
            div.innerHTML = _template['block-mp'].getText(d);
        }
    }

    function _drawOptions() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var d = {};
        _populateOptions(d);
        var div = document.getElementById('mp-options');
        if (div) {
            div.innerHTML = d['mp-options'];
        } else {
            var div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _template['block-mp'].getText(d);
            }
        }
    }

    function _drawOddsTable() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var d = {};
        _populateOddsTable(d);
        var div = document.getElementById('odds-display');
        if (div) {
            div.innerHTML = d['odds-table'];
        } else {
            var div = document.getElementById('module-odds-display');
            if (div && _syn.version > 0) {
                div.innerHTML = _template['block-mp'].getText(d);
            }
        }
    }

    function _drawLoading() {
        if (_syn.version == 0 && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_template && _template['loading']) {
                    text = _template['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _populateOptions(d) {
        var dd = {};
        var i = 0;
        var sport;
        var date;
        var lis = [];
        if (_sports && _sports.length > 0) {
            for (i = 0; i < _sports.length; i++) {
                sport = _sports[i];
                dd['sport-id'] = sport[0];
                dd['sport-name'] = sport[1];
                dd['sel'] = (sport[2] == 1) ? 'sel' : '';
                lis.push(_template['mp-sport-selection'].getText(dd));
            }
        }
        d['mp-sport-selections'] = lis.join('');
        lis = [];
        if (_sports && _dates.length > 0) {
            for (i = 0; i < _dates.length; i++) {
                date = _dates[i];
                dd['date-id'] = date[0];
                dd['date-caption'] = date[1];
                dd['sel'] = (date[2] == 1) ? 'sel' : '';
                if (date[2] == 1) {
                    _dataParam.setValue('date', date[0]);
                }
                lis.push(_template['mp-date-selection'].getText(dd));
            }
        }
        d['mp-date-selections'] = lis.join('');
        d['MaxPayout'] = _maxPayout;
        d['HalftMaxPayout'] = _halfMaxPayout;
        d['mp-options'] = _template['mp-options'].getText(d);
        d['refresh-count'] = _syn.refreshCount;
        d['refresh-button'] = _syn.cooldownCount ? _template['refresh-refreshing'].getText() : _template['refresh-countdown'].getText(d);
    }

    function _populateOddsTable(d) {
        $M('odds-display').clearRef();
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var sportPrefix = _getTemplatePrefix();
        d['col-span'] = _template[sportPrefix + 'colspan'].getText({});
        var tagEventResults = _nonliveCache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        _selectedOddDictionary = $M('ticket').getOddsIdDictionary();
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var oddsFTime1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTime1X2] : null;
            var oddsFHalf1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalf1X2] : null;
            var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
            var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
            var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
            var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
            var oddsML = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.ML] : null;
            var oddsFTimeOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOE] : null;
            var oddsFHalfOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOE] : null;
            var rowCount = 0;
            if (oddsFTime1X2 && rowCount < oddsFTime1X2.length) {
                rowCount = oddsFTime1X2.length;
            }
            if (oddsFHalf1X2 && rowCount < oddsFHalf1X2.length) {
                rowCount = oddsFHalf1X2.length;
            }
            if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
                rowCount = oddsFTimeHDP.length;
            }
            if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
                rowCount = oddsFHalfHDP.length;
            }
            if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
                rowCount = oddsFTimeOU.length;
            }
            if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
                rowCount = oddsFHalfOU.length;
            }
            if (oddsML && rowCount < oddsML.length) {
                rowCount = oddsML.length;
            }
            if (oddsFTimeOE && rowCount < oddsFTimeOE.length) {
                rowCount = oddsFTimeOE.length;
            }
            if (oddsFHalfOE && rowCount < oddsFHalfOE.length) {
                rowCount = oddsFHalfOE.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                rowCount = 1;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, _template['tournament-info']);
                rows.push(_template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? _template['icon-video-nonlive'].getText(d) : '';
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = _template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = _template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = _template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = _template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = _template['showtime-date-time'].getText(d);
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = _template['icon-statistics'].getText(d);
            }
            d['draw'] = _template['draw'].getText();
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 1)) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = _nonliveCache.getEventMoreOddsCount(eventResultId);
            d['icon-more'] = d['odds-count'] ? _template['icon-more'].getText(d) : '';
            d['sub-row'] = '';
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                var has1X2 = false;
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['home-color-class'] = hdp > 0 ? 'red' : 'blue';
                d['away-color-class'] = hdp < 0 ? 'red' : 'blue';
                odds = oddsFTime1X2 ? oddsFTime1X2[rowIndex] : null;
                _populateOdds(d, odds, _MarketDisplay.FTime1X2);
                if (odds != null) {
                    has1X2 = true;
                }
                odds = oddsFHalf1X2 ? oddsFHalf1X2[rowIndex] : null;
                _populateOdds(d, odds, _MarketDisplay.FHalf1X2);
                if (odds != null) {
                    has1X2 = true;
                }
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                _populateOdds(d, odds, _MarketDisplay.FTimeHDP);
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                _populateOdds(d, odds, _MarketDisplay.FHalfHDP);
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
                _populateOdds(d, odds, _MarketDisplay.FTimeOU);
                odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
                _populateOdds(d, odds, _MarketDisplay.FHalfOU);
                odds = oddsFTimeOE ? oddsFTimeOE[rowIndex] : null;
                _populateOdds(d, odds, _MarketDisplay.FTimeOE);
                odds = oddsFHalfOE ? oddsFHalfOE[rowIndex] : null;
                _populateOdds(d, odds, _MarketDisplay.FHalfOE);
                odds = oddsML ? oddsML[rowIndex] : null;
                _populateOdds(d, odds, _MarketDisplay.ML);
                d['row-index'] = oddsRowIndex++;
                var templateRowName = sportPrefix + 'row-event';
                if (templateRowIndex & 1) {
                    templateRowName = templateRowName + '-alt';
                }
                rows.push(_template[templateRowName].getText(d));
                oddsRowIndex++;
                d['icon-more'] = null;
                d['icon-statistics'] = null;
                d['icon-video'] = null;
                d['showtime'] = null;
                d['home'] = null;
                d['away'] = null;
                d['draw'] = null;
                d['sub-row'] = 'subrow';
            }
            if ($M('more').isMoreOpened(eventResultId, 1)) {
                var moreContent = $M('more').getContent(d['col-span']);
                rows.push(moreContent);
            }
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(_template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(_template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.refreshCount;
        d['refresh-button'] = _syn.cooldownCount ? _template['refresh-refreshing'].getText() : _template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['odds-table'] = _template[sportPrefix + 'table'].getText(d);
        } else if (_syn.version == 0 && _nonliveCache.isEmpty()) {
            _drawLoading();
            return;
        } else {
            d['rows'] = _template['row-nodata'].getText(d);
            d['odds-table'] = _template[sportPrefix + 'table'].getText(d);
        }
    }

    function _drawRefreshButtons() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var a = document.getElementById('bu:od:refresh:button');
        if (a) {
            if (_syn.cooldownCount) {
                a.innerHTML = _template['refresh-refreshing'].getText();
            } else if (a.isHover) {
                a.innerHTML = _template['refresh'].getText();
            } else {
                a.innerHTML = _template['refresh-countdown'].getText({
                    'refresh-count': _syn.refreshCount
                });
            }
        }
    }

    function _populateOdds(d, odds, marketDisplayId) {
        if (odds) {
            var indicators = _nonliveCache.getPriceAdjustIndicators(odds[0]);
            OddsUtility.populateOdds(d, odds, _template['price-text'], indicators, null, null, _selectedOddDictionary);
            OddsUtility.populateOddsPoints(d, odds);
            OddsUtility.populateOddsLabels(d, odds);
            OddsUtility.populateOddsIndicators(d, odds, _nonliveCache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
        } else {
            OddsUtility.clearOdds(d, marketDisplayId);
            OddsUtility.clearOddsPoints(d, marketDisplayId);
            OddsUtility.clearOddsLabels(d, marketDisplayId);
            OddsUtility.clearOddsIndicators(d, marketDisplayId);
        }
    }

    function _getTemplatePrefix() {
        switch (parseInt(_dataParam.getValue('sport'))) {
        case 1:
            return 'soccer-';
        case 2:
            return 'basketball-';
        case 3:
        case 25:
            return 'football-';
        case 9:
            return 'baseball-';
        case 13:
        case 31:
            return 'boxing-';
        case 14:
            return 'cricket-';
        case 17:
            return 'handball-';
        case 28:
            return 'winter-';
        default:
            return 'motor-';
        }
    }
}

function __Module_Outright(refreshRate) {
    var _MarketDisplay = {
        Outright: 39
    };
    var _TemplateNameLive = 'odds-display/outright-live';
    var _TemplateNameNonlive = 'odds-display/outright-nonlive';
    var _self = this;
    var _templateLive = null;
    var _templateNonlive = null;
    var _liveCache = new __Cache_Outright(1);
    var _nonliveCache = new __Cache_Outright(1);
    var _moreBlockInfo = [0, 0];
    var _syn = {
        liveWaitingTemplate: false,
        liveDrawing: false,
        liveRefreshRate: refreshRate[0],
        liveRefreshCount: 0,
        liveCooldownCount: 0,
        liveFailureCount: 0,
        liveVersion: 0,
        nonliveWaitingTemplate: false,
        nonliveDrawing: false,
        nonliveRefreshRate: refreshRate[1],
        nonliveRefreshCount: 0,
        nonliveCooldownCount: 0,
        nonliveFailureCount: 0,
        nonliveVersion: 0,
        nonliveWaitToDraw: false
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateNameLive);
        if (templateText) {
            _templateLive = TiLib.Template.createTemplates(templateText);
        }
        templateText = $P.getTemplate(_TemplateNameNonlive);
        if (templateText) {
            _templateNonlive = TiLib.Template.createTemplates(templateText);
        }
        if (_templateNonlive || _templateLive) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateNameLive) {
            var templateText = $P.getTemplate(_TemplateNameLive);
            if (templateText) {
                _templateLive = TiLib.Template.createTemplates(templateText);
                if (_templateLive) {
                    if (_syn.liveWaitingTemplate) {
                        _syn.liveWaitingTemplate = false;
                        _drawLive();
                    }
                    if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
        if (name == _TemplateNameNonlive) {
            var templateText = $P.getTemplate(_TemplateNameNonlive);
            if (templateText) {
                _templateNonlive = TiLib.Template.createTemplates(templateText);
                if (_templateNonlive) {
                    if (_syn.nonliveWaitingTemplate) {
                        _syn.nonliveWaitingTemplate = false;
                        _drawNonlive();
                    }
                    if (_syn.nonliveVersion == 0 && _nonliveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
    };
    this.onIdle = function (data) {
        var version = data[0];
        var frameIndex = data[1];
        if (frameIndex == 0) {
            if (_syn.liveVersion < version) {
                _syn.liveVersion = version;
            }
            if (_liveCache.clearAdjustIndicators()) {
                _drawLive();
            }
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
            }
            if (_nonliveCache.clearAdjustIndicators()) {
                _drawNonlive();
            }
            _syn.nonliveDrawing = false;
        }
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var frameIndex = data[1];
        var clearAll = data[2];
        var frameData = data[3];
        var isChanged = false;
        if (frameIndex == 0) {
            if (_liveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.liveVersion < version) {
                _syn.liveVersion = version;
                if (_liveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (isChanged) {
                _drawLive();
                if (_syn.nonliveWaitToDraw) {
                    _syn.nonliveWaitToDraw = false;
                    _drawNonlive();
                }
            }
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_nonliveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
                if (_nonliveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (isChanged) {
                if (_syn.liveVersion <= 0 && _nonliveCache.isEmpty()) {
                    _syn.nonliveWaitToDraw = true;
                } else {
                    _drawNonlive();
                }
            }
            _syn.nonliveDrawing = false;
        }
    };

    function _submitLive() {
        var sb = [];
        sb.push('odds-display/outright-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=0&v=');
        sb.push(_syn.liveVersion);
        return TiLib.Ajax.sendRequest('outright-live', sb.join(''));
    }

    function _submitNonlive() {
        var sb = [];
        sb.push('odds-display/outright-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=1&v=');
        sb.push(_syn.nonliveVersion);
        return TiLib.Ajax.sendRequest('outright-nonlive', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.liveCooldownCount) {
            _syn.liveCooldownCount--;
        } else if (_syn.liveDrawing) {
            if (_syn.liveFailureCount > 3) {
                _syn.liveDrawing = false;
            } else {
                _syn.liveFailureCount++;
            }
        } else if (_syn.liveRefreshCount > 0) {
            _drawRefreshButtons('live');
            _syn.liveRefreshCount--;
        } else {
            _syn.liveRefreshCount = _syn.liveRefreshRate;
            _syn.liveCooldownCount = 2;
            _syn.liveDrawing = true;
            _syn.liveFailureCount = 0;
            _submitLive();
            _drawRefreshButtons('live');
        }
        if (_syn.nonliveCooldownCount) {
            _syn.nonliveCooldownCount--;
        } else if (_syn.nonliveDrawing) {
            if (_syn.nonliveFailureCount > 3) {
                _syn.nonliveDrawing = false;
            } else {
                _syn.nonliveFailureCount++;
            }
        } else if (_syn.nonliveRefreshCount > 0) {
            _drawRefreshButtons('nonlive');
            _syn.nonliveRefreshCount--;
        } else {
            _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
            _syn.nonliveCooldownCount = 2;
            _syn.nonliveDrawing = true;
            _syn.nonliveFailureCount = 0;
            _submitNonlive();
            _drawRefreshButtons('nonlive');
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('live');
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('nonlive');
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('live');
                        }, 200);
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('nonlive');
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.liveVersion = 0;
            _syn.nonliveVersion = 0;
        } else if (_syn.liveDrawing || _syn.nonliveDrawing || _syn.liveCooldownCount || _syn.nonliveCooldownCount) {
            return;
        }
        _syn.liveRefreshCount = _syn.liveRefreshRate;
        _syn.liveCooldownCount = 2;
        _syn.liveDrawing = true;
        _syn.liveFailureCount = 0;
        _submitLive();
        _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
        _syn.nonliveCooldownCount = 2;
        _syn.nonliveDrawing = true;
        _syn.nonliveFailureCount = 0;
        _submitNonlive();
        _drawRefreshButtons();
    };
    this.refreshLive = function (clearAll) {
        if (!_syn.liveCooldownCount) {
            if (_syn.liveDrawing) {
                if (_syn.liveFailureCount > 3) {
                    _syn.liveDrawing = false;
                } else {
                    _syn.liveFailureCount++;
                }
            } else {
                if (clearAll) {
                    _syn.liveVersion = 0;
                }
                _syn.liveRefreshCount = _syn.liveRefreshRate;
                _syn.liveCooldownCount = 2;
                _syn.liveDrawing = true;
                _syn.liveFailureCount = 0;
                _submitLive();
                _drawRefreshButtons('live');
            }
        }
    };
    this.refreshNonlive = function (clearAll) {
        if (!_syn.nonliveCooldownCount) {
            if (_syn.nonliveDrawing) {
                if (_syn.nonliveFailureCount > 3) {
                    _syn.nonliveDrawing = false;
                } else {
                    _syn.nonliveFailureCount++;
                }
            } else {
                if (clearAll) {
                    _syn.nonliveVersion = 0;
                }
                _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
                _syn.nonliveCooldownCount = 2;
                _syn.nonliveDrawing = true;
                _syn.nonliveFailureCount = 0;
                _submitNonlive();
                _drawRefreshButtons('nonlive');
            }
        }
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_templateLive) {
            _syn.liveWaitingTemplate = true;
            return;
        }
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        _populateNonliveSection(d);
        var div = document.getElementById('module-odds-display');
        if (div) {
            div.innerHTML = _templateLive['odds-display'].getText(d);
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
    }

    function _drawLive() {
        if (!_templateLive) {
            _syn.liveWaitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        var div = document.getElementById('odds-display-live');
        if (div) {
            div.innerHTML = d['odds-display-live'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _templateLive['odds-display'].getText(d);
            }
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
    }

    function _drawNonlive() {
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        var d = {};
        _populateNonliveSection(d);
        var div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.innerHTML = d['odds-display-nonlive'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _templateNonlive['odds-display'].getText(d);
            }
        }
    }

    function _drawLoading() {
        if (_syn.liveVersion == 0 && _syn.nonliveVersion == 0 && _liveCache.isEmpty() && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_templateLive && _templateLive['loading']) {
                    text = _templateLive['loading'].getText();
                } else if (_templateNonlive && _templateNonlive['loading']) {
                    text = _templateNonlive['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _populateLiveSection(d) {
        $M('odds-display').clearRef();
        var template = _templateLive;
        var cache = _liveCache;
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagOutrightArray = cache.getTagOutrightArray();
        var c = tagOutrightArray.length;
        var rows = [];
        var tournamentId = 0;
        var outrightRowIndex = 0;
        var selectedOddId = $M('ticket').getOddIdOption();
        var isLiveOdd = $M('ticket').isLiveTicket();
        d['market-page'] = template['market-page-outright'].getText();
        d['live-ext'] = template['live-ext'].getText();
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        var tournamentAllRows = [];
        for (var i = 0; i < c; ++i) {
            var eachTagOutright = tagOutrightArray[i];
            var tournament = eachTagOutright[1];
            var outright = eachTagOutright[2];
            if (!outright) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                if (tournamentAllRows.length > 0) {
                    var sortedRows = _sortORData(tournamentAllRows, template);
                    rows.push(sortedRows);
                    tournamentAllRows = [];
                }
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                OddsUtility.populateShowTime(d, outright[7], usesLocalTime);
                rows.push(template['row-tournament'].getText(d));
            }
            d['team-name'] = TiLib.Text.encodeHTML(outright[6]);
            var price = TiLib.Number.toString(outright[2], 3, 2);
            d['price-outright-text'] = template['price-text'].getText({
                'odds-id': outright[0],
                'price-value': price,
                'is-live': '1'
            });
            d['row-index'] = i;
            d['bg-color'] = (i & 1) ? '#FFDDCC' : '#FFDDCC';
            var selectedClass = 'dummy-class';
            if (outright[0] + 'or' == selectedOddId && isLiveOdd) {
                selectedClass = 'odds-selected';
            }
            d['price-text-class'] = ((cache.getPriceAdjustIndicators(outright[0])) ? 'odds-change' : '') + selectedClass;
            tournamentAllRows.push(template['row-outright'].getText(d));
        }
        if (tournamentAllRows.length > 0) {
            var sortedRows = _sortORData(tournamentAllRows, template);
            rows.push(sortedRows);
        }
        var ret = 0;
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['refresh-count'] = _syn.liveRefreshCount;
            d['refresh-button'] = _syn.liveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-live'] = template['odds-display-live'].getText(d);
            ret = rows.length;
        } else if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
            _drawLoading();
            ret = 0;
        } else {
            d['odds-display-live'] = '';
            ret = 0;
        }
        return ret;
    }

    function _sortORData(t, template) {
        var sb = [];
        var len = t.length;
        var totRow = Math.floor(len / 2) + (len % 2);
        var left = [];
        var right = [];
        for (var i = 0; i < totRow; i++) {
            left.push(t[i]);
            if ((totRow + i) < len) {
                right.push(t[totRow + i]);
            }
        }
        var d = {};
        d['l-r-ind'] = 'l';
        d['rows'] = left.join('');
        sb.push(template['table-outright-half-section'].getText(d));
        if (right.length > 0) {
            d = {};
            d['l-r-ind'] = 'r';
            d['rows'] = right.join('');
            sb.push(template['table-outright-half-section'].getText(d));
        }
        d['wrapper-data'] = sb.join('');
        return template['table-outright-wrap'].getText(d);
    }

    function _populateNonliveSection(d) {
        $M('odds-display').clearRef();
        var template = _templateNonlive;
        var cache = _nonliveCache;
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagOutrightArray = cache.getTagOutrightArray();
        var c = tagOutrightArray.length;
        var rows = [];
        var tournamentId = 0;
        var outrightCount = 0;
        var selectedOddId = $M('ticket').getOddIdOption();
        var isNonliveOdd = !$M('ticket').isLiveTicket();
        d['market-page'] = template['market-page-outright'].getText();
        d['nonlive-ext'] = template['nonlive-ext'].getText();
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        var tournamentCount = 0;
        var tournamentAllRows = [];
        for (var i = 0; i < c; ++i) {
            var eachTagOutright = tagOutrightArray[i];
            var tournament = eachTagOutright[1];
            var outright = eachTagOutright[2];
            if (!outright) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                if (tournamentAllRows.length > 0) {
                    var sortedRows = _sortORData(tournamentAllRows, template);
                    rows.push(sortedRows);
                    tournamentAllRows = [];
                }
                if (tournamentCount >= limitedRow) {
                    if (!$M('global').hasVerticalScroll()) {
                        if (tournamentCount >= (limitedRow * 2)) {
                            $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                            tournamentCount = Number.MAX_VALUE;
                            break;
                        }
                    } else {
                        tournamentCount = Number.MAX_VALUE;
                        break;
                    }
                }
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                OddsUtility.populateShowTime(d, outright[7], usesLocalTime);
                rows.push(template['row-tournament'].getText(d));
                tournamentCount++;
            }
            d['team-name'] = TiLib.Text.encodeHTML(outright[6]);
            var price = TiLib.Number.toString(outright[2], 3, 2);
            d['price-outright-text'] = template['price-text'].getText({
                'odds-id': outright[0],
                'price-value': price,
                'is-live': '1'
            });
            d['row-index'] = i;
            var selectedClass = 'dummy-class';
            if (outright[0] + 'or' == selectedOddId && isNonliveOdd) {
                selectedClass = 'odds-selected';
            }
            d['price-text-class'] = ((cache.getPriceAdjustIndicators(outright[0])) ? 'odds-change' : '') + selectedClass;
            var rowTemplate = (i % 2 == 0) ? 'row-outright' : 'row-outright-alt';
            tournamentAllRows.push(template[rowTemplate].getText(d));
            outrightCount++;
        }
        if (tournamentAllRows.length > 0) {
            var sortedRows = _sortORData(tournamentAllRows, template);
            rows.push(sortedRows);
        }
        if (tournamentCount == Number.MAX_VALUE) {
            rows.push(template['row-loading'].getText());
        }
        if (outrightCount == c) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.nonliveRefreshCount;
        d['refresh-button'] = _syn.nonliveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        } else if (cache.isEmpty() && _syn.nonliveVersion == 0) {
            _drawLoading();
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        }
    }

    function _drawRefreshButtons(section) {
        if (!_templateLive) {
            _syn.waitingTemplate = true;
            return;
        }
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        if (section === undefined || section == 'live') {
            var a = document.getElementById('bu:od:refresh-live:button');
            if (a) {
                if (_syn.liveCooldownCount) {
                    a.innerHTML = _templateLive['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _templateLive['refresh'].getText();
                } else {
                    a.innerHTML = _templateLive['refresh-countdown'].getText({
                        'refresh-count': _syn.liveRefreshCount
                    });
                }
            }
        }
        if (section === undefined || section == 'nonlive') {
            a = document.getElementById('bu:od:refresh-nonlive:button');
            if (a) {
                if (_syn.nonliveCooldownCount) {
                    a.innerHTML = _templateNonlive['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _templateNonlive['refresh'].getText();
                } else {
                    a.innerHTML = _templateNonlive['refresh-countdown'].getText({
                        'refresh-count': _syn.nonliveRefreshCount
                    });
                }
            }
        }
    }
}

function __Module_OddsDisplay(oddsDisplayParam, displayInLocalTime, oddsDisplayInitialParams, daylightTypePeriod) {
    var _self = this;
    var _submodule = null;
    var _displayInLocalTime = displayInLocalTime;
    var _daylightType = 0;
    var _daylightTypePeriod = daylightTypePeriod;
    var _oddsDisplayInitialParams = oddsDisplayInitialParams;
    var _oddsDisplayParam = oddsDisplayParam;
    this.getOddsDisplayParam = function () {
        return _oddsDisplayParam.getJoinedValues();
    }
    var _show1X2DC = 1;
    var _showFTCS = 1;
    var _limitedRows = 50;
    var _lastExtended = new Date();
    var _additionalRows = 50;
    this.initiate = function () {
        TiLib.Timer.addToSecondTimer(_self);
        _replaceSubmodule();
    };
    this.onTemplate = function (name, extension) {
        if (_submodule && _submodule.onTemplate) {
            _submodule.onTemplate(name, extension);
        }
    };
    this.onIdle = function (token, data) {
        if (token == _oddsDisplayParam.getValue('token')) {
            if (_submodule && _submodule.onIdle) {
                _submodule.onIdle(data);
            }
        }
    };
    this.onUpdate = function (token, data) {
        if (token == _oddsDisplayParam.getValue('token')) {
            if (_submodule && _submodule.onUpdate) {
                _submodule.onUpdate(data);
            }
        }
    }
    this.onUpdateFavourite = function (token, data) {
        if (token == _oddsDisplayParam.getValue('token')) {
            if (_submodule && _submodule.onUpdateFavourite) {
                _submodule.onUpdateFavourite(data);
            }
        }
    }
    this.onChangeDisplaySetting = function (token, key, value) {
        if (token == _oddsDisplayParam.getValue('token')) {
            _oddsDisplayParam.setValue(key, value);
        }
    };
    this.extend = function () {
        var now = new Date();
        var enabled = _oddsDisplayInitialParams['limitedDisplayEnabled'];
        if (enabled) {
            if (now - _lastExtended >= 200 && _limitedRows < Number.MAX_VALUE) {
                _limitedRows += _additionalRows;
                if (_submodule && _submodule.draw) {
                    _submodule.draw();
                }
                _lastExtended = new Date();
            }
        }
    }
    this.onTime = function () {
        if (_submodule && _submodule.onTime) {
            _submodule.onTime();
        }
    };
    var _hadReloaded = false;
    this.onReload = function () {
        if (!_hadReloaded) {
            _hadReloaded = true;
            var minutes = Math.random() * 300;
            setTimeout(function () {
                document.location.replace(document.location.href);
            }, minutes * 1000);
        }
    };
    this.onSettingChanged = function () {
        var needsReplaceModule = false;
        var needsRefresh = false;
        var needsDraw = false;
        var names = CookieHelper.getNames('od-param-');
        var c = names.length;
        for (var i = 0; i < c; ++i) {
            var value = CookieHelper.getValue(names[i]);
            if (value && value !== null) {
                var key = names[i].substring('od-param-'.length);
                switch (key) {
                case 'display-in-local-time':
                    _displayInLocalTime = value;
                    needsDraw = true;
                    break;
                case 'odds-mode':
                    _increaseToken();
                    _oddsDisplayParam.setValue(key, value);
                    needsReplaceModule = true;
                    break;
                case 'price-style':
                    _increaseToken();
                    _oddsDisplayParam.setValue(key, value);
                    needsRefresh = true;
                    break;
                case 'sorting':
                case 'market-showing':
                    _oddsDisplayParam.setValue(key, value);
                    needsDraw = true;
                    break;
                }
            }
        }
        if (needsReplaceModule) {
            _replaceSubmodule();
        } else if (needsRefresh) {
            if (_submodule && _submodule.refresh) {
                _submodule.refresh(true);
            }
        } else if (needsDraw) {
            if (_submodule && _submodule.draw) {
                _submodule.draw();
            }
        }
    };
    this.onClick = function (event) {
        if (!event) event = window.event;
        if (_submodule && _submodule.onClick && !_submodule.onClick(event)) {
            event.returnValue = false;
            return false;
        }
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    };

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            var element = e;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'od') {
                switch (atom[2]) {
                case 'refresh':
                    _self.refresh();
                    return false;
                case 'refresh-live':
                    _self.refreshLive();
                    return false;
                case 'refresh-nonlive':
                    _self.refreshNonlive();
                    return false;
                case 'select-tournament':
                    if (count >= 4) {
                        $M('select-tournament').open(atom[3]);
                    }
                    return false;
                case 'statistics':
                    if (count >= 4) {
                        OddsUtility.openStatistics(atom[3]);
                        if ($M('global') && $M('global').incGA) {
                            $M('global').incGA('statistics', 'center');
                        }
                    }
                    return false;
                case 'price':
                    if (count >= 6) {
                        var oddsSource = _getOddsSource(e);
                        _openTicket(atom[3], atom[4], atom[5], atom[6], "s", false, oddsSource, element, id);
                    }
                    return false;
                case 'mpprice':
                    if (count >= 6) {
                        var oddsSource = _getOddsSource(e);
                        _openTicket(atom[3], atom[4], atom[5], atom[6], "mp", false, oddsSource, element, id);
                    }
                    return false;
                case 'orprice-live':
                    if (count >= 6) {
                        _openTicket(atom[3], atom[4], atom[5], atom[6], "or", true, null, element, id);
                    }
                    return false;
                case 'orprice-nonlive':
                    if (count >= 6) {
                        _openTicket(atom[3], atom[4], atom[5], atom[6], "or", false, null, element, id);
                    }
                    return false;
                case 'sorting':
                    if (count >= 4) {
                        _self.setDisplaySetting('sorting', parseInt(atom[3]));
                    }
                    return false;
                case 'market-showing':
                    if (count >= 4) {
                        _self.setDisplaySetting('market-showing', parseInt(atom[3]));
                    }
                    return false;
                case 'price-style':
                    if (count >= 4) {
                        _self.setDisplaySetting('price-style', parseInt(atom[3]));
                    }
                    return false;
                case 'odds-mode':
                    if (count >= 4) {
                        _self.setDisplaySetting('odds-mode', parseInt(atom[3]));
                    }
                    return false;
                case 'event-date':
                    if (count >= 4) {
                        _self.setDisplaySetting('event-date', parseInt(atom[3]));
                    }
                    return false;
                case '1x2dc':
                    if (count >= 4) {
                        _self.setDisplaySetting('1x2dc', parseInt(atom[3]));
                    }
                    return false;
                case 'csft':
                    if (count >= 4) {
                        _self.setDisplaySetting('csft', parseInt(atom[3]));
                    }
                    return false;
                case 'live-more':
                    if (count >= 4) {
                        var eventResultId = parseInt(atom[3]);
                        element.className = TiLib.Text.addClassItem(element.className, 'more-loading');
                        if ($M('more').isMoreOpened(eventResultId, 0)) {
                            $M('more').closeMoreBlock();
                        } else {
                            $M('more').openMoreBlock(eventResultId, 0, _getMarketFrameId(true));
                        }
                        if ($M('global') && $M('global').incGA) {
                            $M('global').incGA('live-more', 'center');
                        }
                    }
                    return false;
                case 'nonlive-more':
                    if (count >= 4) {
                        var eventResultId = parseInt(atom[3]);
                        element.className = TiLib.Text.addClassItem(element.className, 'more-loading');
                        if ($M('more').isMoreOpened(eventResultId, 1)) {
                            $M('more').closeMoreBlock();
                        } else {
                            $M('more').openMoreBlock(eventResultId, 1, _getMarketFrameId(false));
                        }
                        if ($M('global') && $M('global').incGA) {
                            $M('global').incGA('nonlive-more', 'center');
                        }
                    }
                    return false;
                case 'video':
                    if (count >= 4) {
                        $M('top-banner').onSBOBETvClick(atom[3], 'center');
                    }
                    return false;
                case 'daylight-type':
                    if (count >= 4) {
                        _self.setDisplaySetting('daylight-type', parseInt(atom[3]));
                    }
                    return false;
                case 'ls':
                    if (count >= 4) {
                        var eventId = atom[3];
                        if (eventId && parseInt(eventId) > 0) {
                            var sportId = _oddsDisplayParam.getValue('sport');
                            CookieHelper.setValue('opened-event-id', parseInt(atom[3]));
                            CookieHelper.setValue('opened-sport-id', sportId);
                            if ($M('global') && $M('global').incGA) {
                                $M('global').incGA('lives-fire', 'center');
                            }
                            if ($M('top-banner') && $M('top-banner').goProduct) {
                                $M('top-banner').goProduct('livesports');
                            } else {
                                var host = document.location.host;
                                var dest = '/web-root/restricted/live-sport/live-sport.aspx';
                                var query = document.location.search;
                                document.location.href = 'http://' + host + dest + query;
                            }
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }
    this.onMouseOver = function (event, id) {
        if (_submodule && _submodule.onMouseOver && !_submodule.onMouseOver(event, id)) {
            event.returnValue = false;
            return false;
        }
    };
    this.onMouseOut = function (event, id) {
        if (_submodule && _submodule.onMouseOut && !_submodule.onMouseOut(event, id)) {
            event.returnValue = false;
            return false;
        }
    };
    var _selectedElements = {};
    var _refNodes = {};
    var _refDummyClassName = {};
    var _firstOpen = false;

    function getElementsByClassName(className, tag, elm) {
        var testClass = new RegExp("(^|\\s)" + className + "(\\s|$)");
        var tag = tag || "*";
        var elm = elm || document;
        var elements = (tag == "*" && elm.all) ? elm.all : elm.getElementsByTagName(tag);
        var returnElements = [];
        var current;
        var length = elements.length;
        for (var i = 0; i < length; i++) {
            current = elements[i];
            if (testClass.test(current.className)) {
                returnElements.push(current);
            }
        }
        return returnElements;
    }

    function _openTicket(oddsId, option, price, hdpType, betType, isLiveOutright, oddsSource, srcElement, id) {
        if (!_firstOpen) {
            var elements = null;
            if (document.getElementsByClassName) {
                elements = document.getElementsByClassName('odds-selected');
            } else {
                elements = getElementsByClassName('odds-selected');
            }
            var selectedOddsElement = [];
            for (var i = 0; i < elements.length; i++) {
                selectedOddsElement.push(elements[i]);
            }
            for (var i = 0; i < selectedOddsElement.length; i++) {
                var node = selectedOddsElement[i];
                var className = node.className;
                var dummyClass = 'dummy-class';
                while (node) {
                    if (node.id) {
                        var ids = node.id.split(':');
                        if (ids[2] == 'price' || ids[2] == 'mpprice') {
                            dummyClass = 'dummy-more-class';
                            break;
                        }
                    }
                    node = node.parentNode;
                }
                selectedOddsElement[i].className = className.replace('odds-selected', dummyClass);
            }
            _firstOpen = true;
            $M('ticket').setDisabledGetOddsIdOption(true);
        }
        switch (betType) {
        case "or":
            $M('ticket').openTicket(oddsId, option, price, hdpType, true, isLiveOutright, $M('ticket').getBetPageEnum('oddsDisplay'));
            if (isLiveOutright) {
                option = 'or';
            } else {
                option = 'or';
            }
            break;
        case "mp":
            $M('ticket').openMPTicket(oddsId, option, price, hdpType);
            break;
        default:
            $M('ticket').openTicket(oddsId, option, price, hdpType, false, isLiveOutright, $M('ticket').getBetPageEnum('oddsDisplay'), oddsSource);
            break;
        }
        if (oddsSource == $M('ticket').getBetPageEnum('favourite')) {
            var element = srcElement;
            while (element) {
                var id = element.id;
                if (id && id.indexOf('more-block-') > -1) {
                    oddsSource = $M('ticket').getBetPageEnum('more');
                    break;
                }
                element = element.parentNode;
            }
        }
        if (oddsSource == $M('ticket').getBetPageEnum('more')) {
            var childs = srcElement.childNodes;
            for (var i = 0; i <= childs.length; i++) {
                if (childs[i] && childs[i].className.indexOf('dummy-more-class') >= 0) {
                    _refNodes[oddsId + option] = childs[i];
                    _refDummyClassName[oddsId + option] = 'dummy-more-class';
                }
            }
        } else {
            while (srcElement) {
                var className = srcElement.className;
                if (className && className.indexOf('dummy-class') >= 0) {
                    _refNodes[oddsId + option] = srcElement;
                    _refDummyClassName[oddsId + option] = 'dummy-class';
                    break;
                }
                srcElement = srcElement.parentNode;
            }
        }
    }

    function _getOddsSource(ev) {
        var marketId = _oddsDisplayParam.getValue('market-page');
        if (marketId == 13) {
            return $M('ticket').getBetPageEnum('favourite');
        } else {
            while (ev) {
                var id = ev.id;
                if (id && id.indexOf('more-block-') > -1) {
                    return $M('ticket').getBetPageEnum('more');
                }
                ev = ev.parentNode;
            }
            var mktframe = _getMarketFrameId(false);
            switch (mktframe) {
            case 1:
            case 6:
                return $M('ticket').getBetPageEnum('doublePage');
            case 2:
            case 7:
                return $M('ticket').getBetPageEnum('singlePage');
            default:
                return '';
            }
        }
        return '';
    }
    this.clearRef = function () {
        _selectedElements = {};
        _refNodes = {};
        _refDummyClassName = {};
        _firstOpen = false;
        $M('ticket').setDisabledGetOddsIdOption(false);
        return;
    }
    this.clearSelectedOdds = function () {
        if (!_firstOpen) {
            var elements = null;
            if (document.getElementsByClassName) {
                elements = document.getElementsByClassName('odds-selected');
            } else {
                elements = getElementsByClassName('odds-selected');
            }
            var selectedOddsElement = [];
            for (var i = 0; i < elements.length; i++) {
                selectedOddsElement.push(elements[i]);
            }
            for (var i = 0; i < selectedOddsElement.length; i++) {
                var node = selectedOddsElement[i];
                var className = node.className;
                var dummyClass = 'dummy-class';
                while (node) {
                    if (node.id) {
                        var ids = node.id.split(':');
                        if (ids[2] == 'price' || ids[2] == 'mpprice') {
                            dummyClass = 'dummy-more-class';
                            break;
                        }
                    }
                    node = node.parentNode;
                }
                selectedOddsElement[i].className = className.replace('odds-selected', dummyClass);
            }
            _firstOpen = true;
            $M('ticket').setDisabledGetOddsIdOption(true);
        }
        for (var selectedOddIdOption in _selectedElements) {
            var node = _refNodes[selectedOddIdOption];
            if (node) {
                var className = node.className;
                node.className = className.replace('odds-selected', _refDummyClassName[selectedOddIdOption]);
            }
        }
        _selectedElements = {};
        var force = true;
        var marketId = _self.getDisplaySetting('market-page');
        var oddIdOption = $M('ticket').getOddIdOption(force);
        if (oddIdOption && marketId != 9) {
            var dummyClassName = _refDummyClassName[oddIdOption];
            if (!dummyClassName) dummyClassName = 'dummy-class';
            var node = _refNodes[oddIdOption];
            if (!node) {
                var oddsOptions = $M('ticket').getOddIdOptions(force);
                var idString = oddsOptions.join(':');
                node = document.getElementById(idString);
                if (!node) {
                    var hdpOptions = ['', 0, 1, 2];
                    for (var i = 0; i < hdpOptions.length; i++) {
                        oddsOptions[oddsOptions.length - 1] = hdpOptions[i];
                        idString = oddsOptions.join(':');
                        node = document.getElementById(idString);
                        if (node) {
                            break;
                        }
                    }
                }
                if (node) {
                    var element = node;
                    while (element) {
                        var className = element.className;
                        if (className && className.indexOf('dummy-class') >= 0) {
                            _refNodes[oddIdOption] = element;
                            _refDummyClassName[oddIdOption] = 'dummy-class';
                            break;
                        }
                        element = element.parentNode;
                    }
                    var childs = node.childNodes;
                    for (var i = 0; i <= childs.length; i++) {
                        if (childs[i] && childs[i].className && childs[i].className.indexOf('dummy-more-class') >= 0) {
                            _refNodes[oddIdOption] = childs[i];
                            _refDummyClassName[oddIdOption] = 'dummy-more-class';
                        }
                    }
                }
                dummyClassName = _refDummyClassName[oddIdOption];
            }
            node = _refNodes[oddIdOption];
            if (node) {
                var className = node.className;
                className = className.replace('odds-change', '');
                node.className = className.replace(dummyClassName, 'odds-selected');
                _selectedElements[oddIdOption] = 1;
            } else {}
        }
        var oddsDictionary = $M('ticket').getOddsIdDictionary(force);
        if (oddsDictionary && marketId == 9) {
            for (var oddIdOption in oddsDictionary) {
                var dummyClassName = _refDummyClassName[oddIdOption];
                if (!dummyClassName) {
                    _refDummyClassName[oddIdOption] = 'dummy-class';
                }
                var node = _refNodes[oddIdOption];
                if (!node) {
                    var mpOptions = oddsDictionary[oddIdOption];
                    var idString = mpOptions.join(':');
                    node = document.getElementById(idString);
                    if (!node) {
                        var hdpOptions = ['', 0, 1, 2];
                        for (var i = 0; i < hdpOptions.length; i++) {
                            mpOptions[mpOptions.length - 1] = hdpOptions[i];
                            idString = mpOptions.join(':');
                            node = document.getElementById(idString);
                            if (node) {
                                break;
                            }
                        }
                    }
                    if (node) {
                        var element = node;
                        while (element) {
                            var className = element.className;
                            if (className && className.indexOf('dummy-class') >= 0) {
                                _refNodes[oddIdOption] = element;
                                _refDummyClassName[oddIdOption] = 'dummy-class';
                                break;
                            }
                            element = element.parentNode;
                        }
                        var childs = node.childNodes;
                        for (var i = 0; i <= childs.length; i++) {
                            if (childs[i] && childs[i].className && childs[i].className.indexOf('dummy-more-class') >= 0) {
                                _refNodes[oddIdOption] = childs[i];
                                _refDummyClassName[oddIdOption] = 'dummy-more-class';
                            }
                        }
                    }
                    dummyClassName = _refDummyClassName[oddIdOption];
                }
                node = _refNodes[oddIdOption];
                if (node) {
                    var className = node.className;
                    className = className.replace('odds-change', '');
                    node.className = className.replace(dummyClassName, 'odds-selected');
                    _selectedElements[oddIdOption] = 1;
                } else {}
            }
        }
    }
    this.refresh = function (clearAll) {
        if (_submodule && _submodule.refresh) {
            _submodule.refresh(clearAll);
        }
    };
    this.refreshLive = function (clearAll) {
        if (_submodule && _submodule.refreshLive) {
            _submodule.refreshLive(clearAll);
        }
    };
    this.refreshNonlive = function (clearAll) {
        if (_submodule && _submodule.refreshNonlive) {
            _submodule.refreshNonlive(clearAll);
        }
    };
    this.draw = function () {
        if (_submodule && _submodule.draw) {
            _submodule.draw();
        }
    };
    this.getDisplaySetting = function (key) {
        switch (key) {
        case 'display-in-local-time':
            return _displayInLocalTime;
        case 'daylight-type-period':
            return _daylightTypePeriod;
        case 'limited-rows':
            if (!_oddsDisplayInitialParams['limitedDisplayEnabled']) {
                _limitedRows = Number.MAX_VALUE;
            }
            return _limitedRows;
        default:
            return _oddsDisplayParam.getValue(key);
        }
    };
    this.setDisplaySetting = function (key, value, position) {
        if (_setDisplaySetting(key, value, position)) {
            return true;
        }
        return false;
    };
    this.setDisplayParam = function (key, value) {
        if (_oddsDisplayParam.setValue(key, value)) {
            return true;
        }
        return false;
    };

    function _setDisplaySetting(key, value, position) {
        switch (key) {
        case 'display-in-local-time':
            _displayInLocalTime = value;
            if (_submodule && _submodule.draw) {
                _submodule.draw();
            }
            break;
        case '1x2dc':
            _show1X2DC = value;
            _increaseToken();
            return _replaceSubmodule();
            break;
        case 'csft':
            _showFTCS = value;
            _increaseToken();
            return _replaceSubmodule();
            break;
        case 'sport-favourite':
            _oddsDisplayParam.setValue('sport', value);
            return _switchSportFavourite();
        case 'limited-rows':
            if (!_oddsDisplayInitialParams['limitedDisplayEnabled']) {
                value = Number.MAX_VALUE;
            }
            _limitedRows = value;
            return;
        default:
            if (_oddsDisplayParam.getValue(key) != value) {
                _oddsDisplayParam.setValue(key, value);
                switch (key) {
                case 'market-page':
                    CookieHelper.setValue('opened-market-id', value);
                    if ($M('global') && $M('global').redrawLeftColumn) {
                        window.scrollTo(0, 0);
                        $M('global').redrawLeftColumn();
                    }
                    _increaseToken();
                    return _replaceSubmodule();
                case 'odds-mode':
                    _increaseToken();
                    return _replaceSubmodule();
                case 'sport':
                    return _switchSport();
                case 'daylight-type':
                    _increaseToken();
                    if (_submodule && _submodule.refresh) {
                        _submodule.refresh(true);
                        return true;
                    }
                    break;
                case 'event-date':
                    _limitedRows = _additionalRows;
                    if (_submodule && _submodule.refresh) {
                        _submodule.refresh(true);
                        return true;
                    }
                    break;
                case 'price-style':
                    _increaseToken();
                    CookieHelper.setValue('od-param-' + key, value);
                    if ($M('interested-event') && $M('interested-event').refresh) {
                        $M('interested-event').refresh(true);
                    }
                    if (_submodule && _submodule.refresh) {
                        _submodule.refresh(true);
                        return true;
                    }
                    break;
                case 'sorting':
                    CookieHelper.setValue('od-param-' + key, value);
                    if (_submodule && _submodule.sort) {
                        _submodule.sort();
                        return true;
                    }
                    break;
                case 'market-showing':
                    CookieHelper.setValue('od-param-' + key, value);
                    if ($M('more').isLiveMoreOpened()) {
                        $M('more').refresh(_getMarketFrameId(true));
                    }
                    if ($M('global') && $M('global').incGA && position) {
                        var category = value == 1 ? 'mainMarket' : 'allMarket';
                        $M('global').incGA(category, position);
                    }
                    if (_submodule && _submodule.draw) {
                        _submodule.draw();
                        return true;
                    }
                    break;
                }
            }
        }
        return false;
    }

    function _increaseToken() {
        _oddsDisplayParam.setValue('token', _oddsDisplayParam.getValue('token') + 1);
    }

    function _switchSport() {
        _oddsDisplayParam.setValue('event-date', 0);
        var sportId = _oddsDisplayParam.getValue('sport');
        CookieHelper.setValue('opened-sport-id', sportId);
        if ($M('global') && $M('global').redrawLeftColumn) {
            window.scrollTo(0, 0);
            $M('global').redrawLeftColumn();
        }
        var marketPageId = _oddsDisplayParam.getValue('market-page');
        var newMarketPageId = $M('sport-market').getNewMarketPageId(sportId, marketPageId);
        if (!newMarketPageId && marketPageId == 13) {
            newMarketPageId = 13;
        }
        if (newMarketPageId != marketPageId) {
            _oddsDisplayParam.setValue('market-page', newMarketPageId);
            CookieHelper.setValue('opened-market-id', newMarketPageId);
            return _replaceSubmodule();
        } else if (_submodule && _submodule.refresh) {
            return _replaceSubmodule();
        }
        return false;
    }

    function _switchSportFavourite() {
        _oddsDisplayParam.setValue('market-page', 13);
        return _replaceSubmodule();
    }

    function _replaceSubmodule() {
        var newSubmodule = null;
        var marketPageId = _oddsDisplayParam.getValue('market-page');
        var sortingType = _oddsDisplayParam.getValue('sorting');
        var oddsDisplayInitialParams = _oddsDisplayInitialParams[marketPageId];
        if (!oddsDisplayInitialParams) {
            oddsDisplayInitialParams = 60;
        }
        _limitedRows = _additionalRows;
        var oddsMode = parseInt(_oddsDisplayParam.getValue('odds-mode'));
        switch (marketPageId) {
        case 1:
            switch (oddsMode) {
            case 2:
                newSubmodule = new __Module_TodaySingle(oddsDisplayInitialParams, sortingType);
                break;
            case 1:
            default:
                newSubmodule = new __Module_TodayDouble(oddsDisplayInitialParams, sortingType);
                break;
            }
            break;
        case 2:
            switch (oddsMode) {
            case 2:
                newSubmodule = new __Module_EarlyMarketSingle(oddsDisplayInitialParams, sortingType);
                break;
            case 1:
            default:
                newSubmodule = new __Module_EarlyMarketDouble(oddsDisplayInitialParams, sortingType);
                break;
            }
            break;
        case 3:
            switch (oddsMode) {
            case 2:
                newSubmodule = new __Module_LiveSingle(oddsDisplayInitialParams, sortingType);
                break;
            case 1:
            default:
                newSubmodule = new __Module_LiveDouble(oddsDisplayInitialParams, sortingType);
                break;
            }
            break;
        case 4:
            newSubmodule = new __Module_OETG(oddsDisplayInitialParams, sortingType);
            break;
        case 5:
            switch (_showFTCS) {
            case 2:
                newSubmodule = new __Module_CS_FH(oddsDisplayInitialParams, sortingType);
                break;
            case 1:
            default:
                newSubmodule = new __Module_CS_FT(oddsDisplayInitialParams, sortingType);
                break;
            }
            break;
        case 6:
            newSubmodule = new __Module_HTFT(oddsDisplayInitialParams, sortingType);
            break;
        case 7:
            switch (_show1X2DC) {
            case 2:
                newSubmodule = new __Module_FT_1X2(oddsDisplayInitialParams, sortingType);
                break;
            case 1:
            default:
                newSubmodule = new __Module_1X2_DC(oddsDisplayInitialParams, sortingType);
                break;
            }
            break;
        case 8:
            newSubmodule = new __Module_FGLG(oddsDisplayInitialParams, sortingType);
            break;
        case 9:
            newSubmodule = new __Module_MixParlay(oddsDisplayInitialParams, sortingType);
            break;
        case 10:
            newSubmodule = new __Module_Outright(oddsDisplayInitialParams);
            break;
        case 13:
            switch (oddsMode) {
            case 2:
                newSubmodule = new __Module_FavouriteSingle(oddsDisplayInitialParams, sortingType);
                break;
            case 1:
            default:
                newSubmodule = new __Module_FavouriteDouble(oddsDisplayInitialParams, sortingType);
                break;
            }
            break;
        }
        $M('more').clearMoreBlockInfo();
        if (newSubmodule != null) {
            if (_submodule != null && _submodule.dispose) {
                _submodule.dispose();
            }
            _submodule = newSubmodule;
            if (_submodule.initiate) {
                _submodule.initiate();
            }
            if (_submodule.refresh) {
                _submodule.refresh(true);
            }
            return true;
        }
        return false;
    }

    function _getMarketFrameId(isLive) {
        var oddsMode = _oddsDisplayParam.getValue('odds-mode');
        switch (_oddsDisplayParam.getValue('market-page')) {
        case 13:
        case 1:
            if (isLive) {
                if (oddsMode == 2) {
                    return 2;
                } else {
                    return 1;
                }
            } else {
                if (oddsMode == 2) {
                    return 7;
                } else {
                    return 6;
                }
            }
        case 2:
            if (oddsMode == 2) {
                return 7;
            } else {
                return 6;
            }
        case 3:
            if (oddsMode == 2) {
                return 2;
            } else {
                return 1;
            }
        case 4:
            if (isLive) {
                return 23;
            } else {
                return 11;
            }
        case 5:
            if (isLive) {
                return 0;
            } else {
                if (_showFTCS != 2) {
                    return 16;
                } else {
                    return 17;
                }
            }
        case 6:
            return 18;
        case 7:
            if (isLive) {
                if (_show1X2DC != 2) {
                    return 12;
                } else {
                    return 14;
                }
            } else {
                if (_show1X2DC != 2) {
                    return 13;
                } else {
                    return 15;
                }
            }
        case 8:
            return 19;
        case 9:
            return 20;
        case 10:
            if (isLive) {
                return 21;
            } else {
                return 22;
            }
        default:
            return 0;
        }
    }
}

function __Module_FavouriteDouble(refreshRate, sortType) {
    var _MarketDisplay = {
        FTime1X2: 5,
        FHalf1X2: 8,
        FTimeHDP: 1,
        FHalfHDP: 7,
        FTimeOU: 3,
        FHalfOU: 9,
        FTimeOE: 2,
        FHalfOE: 12,
        ML: 11,
        FTimeLS: 16
    };
    var _SportNameNonlive = {
        1: 'soccer',
        2: 'basketball',
        3: 'football',
        7: 'motor',
        9: 'baseball',
        13: 'boxing',
        14: 'cricket',
        17: 'handball',
        28: 'winter',
        31: 'boxing'
    };
    var _SportNameLive = {
        9: 'baseball'
    };
    var _NonliveColSpan = {
        1: 11,
        2: 10,
        3: 10,
        7: 8,
        9: 10,
        13: 7,
        14: 7,
        17: 7,
        28: 6,
        31: 7
    };
    var _TemplateNameLive = 'odds-display/today-double-live';
    var _TemplateNameNonlive = 'odds-display/today-double-nonlive';
    var _TemplateNameFavourite = 'left-column/favourite';
    var _self = this;
    var _templateLive = null;
    var _templateNonlive = null;
    var _templateFavourite = null;
    var _liveCache = new __Cache_Event(sortType);
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _daylightPeriod = 0;
    var _syn = {
        liveWaitingTemplate: false,
        liveDrawing: false,
        liveRefreshRate: refreshRate[0],
        liveRefreshCount: 0,
        liveCooldownCount: 0,
        liveFailureCount: 0,
        liveVersion: 0,
        nonliveWaitingTemplate: false,
        nonliveDrawing: false,
        nonliveRefreshRate: refreshRate[1],
        nonliveRefreshCount: 0,
        nonliveCooldownCount: 0,
        nonliveFailureCount: 0,
        nonliveVersion: 0,
        nonliveWaitToDraw: false,
        favouriteWaitingTemplate: false
    };
    this.initiate = function () {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        var extentLive = _SportNameLive[sportId];
        if (!extentLive) extentLive = 'soccer';
        var templateText = $P.getTemplate(_TemplateNameLive + '-' + extentLive);
        if (templateText) {
            _templateLive = TiLib.Template.createTemplates(templateText);
        }
        var extentNonlive = _SportNameNonlive[sportId];
        if (!extentNonlive) extentNonlive = 'motor';
        templateText = $P.getTemplate(_TemplateNameNonlive + '-' + extentNonlive);
        if (templateText) {
            _templateNonlive = TiLib.Template.createTemplates(templateText);
        }
        templateText = $P.getTemplate(_TemplateNameFavourite);
        if (templateText) {
            _templateFavourite = TiLib.Template.createTemplates(templateText);
        }
        if (_templateNonlive || _templateLive || _templateFavourite) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        var extentLive = _SportNameLive[sportId];
        if (!extentLive) extentLive = 'soccer';
        if (name == _TemplateNameLive + '-' + extentLive) {
            var templateText = $P.getTemplate(_TemplateNameLive + '-' + extentLive);
            if (templateText) {
                _templateLive = TiLib.Template.createTemplates(templateText);
                if (_templateLive) {
                    if (_syn.liveWaitingTemplate) {
                        _syn.liveWaitingTemplate = false;
                        _drawLive();
                    }
                    if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
        var extentNonlive = _SportNameNonlive[sportId];
        if (!extentNonlive) extentNonlive = 'motor';
        if (name == _TemplateNameNonlive + '-' + extentNonlive) {
            var templateText = $P.getTemplate(_TemplateNameNonlive + '-' + extentNonlive);
            if (templateText) {
                _templateNonlive = TiLib.Template.createTemplates(templateText);
                if (_templateNonlive) {
                    if (_syn.nonliveWaitingTemplate) {
                        _syn.nonliveWaitingTemplate = false;
                        _drawNonlive();
                    }
                    if (_syn.nonliveVersion == 0 && _nonliveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
        if (name == _TemplateNameFavourite) {
            var templateText = $P.getTemplate(_TemplateNameFavourite);
            if (templateText) {
                _templateFavourite = TiLib.Template.createTemplates(templateText);
                if (_templateFavourite) {
                    if (_syn.favouriteWaitingTemplate) {
                        _syn.favouriteWaitingTemplate = false;
                        _drawLive();
                        _drawNonlive();
                    }
                }
            }
        }
    };
    this.onIdle = function (data) {
        var version = data[0];
        var frameIndex = data[1];
        if (frameIndex == 0) {
            if (_syn.liveVersion < version) {
                _syn.liveVersion = version;
            }
            _liveCache.clearAdjustIndicators();
            _drawLive();
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
            }
            _nonliveCache.clearAdjustIndicators();
            _drawNonlive();
            _syn.nonliveDrawing = false;
        }
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var frameIndex = data[1];
        var clearAll = data[2];
        var frameData = data[3];
        var mediaData = data[4];
        var daylightType = data[5];
        var favouriteCacheData = data[6];
        var isChanged = false;
        if (frameIndex == 0) {
            if (_liveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.liveVersion < version) {
                _syn.liveVersion = version;
                if (_liveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (favouriteCacheData) {
                $M('favourite').onUpdate(favouriteCacheData);
            }
            if (isChanged) {
                _drawLive();
                if (_syn.nonliveWaitToDraw) {
                    _syn.nonliveWaitToDraw = false;
                    _drawNonlive();
                }
            }
            if (!isChanged) {
                _drawLive();
            }
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_nonliveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
                if (_nonliveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (favouriteCacheData) {
                $M('favourite').onUpdate(favouriteCacheData);
            }
            if (daylightType && daylightType.length >= 2) {
                _daylightPeriod = daylightType[1];
                $M('odds-display').setDisplaySetting('daylight-type-period', daylightType[1]);
                $M('odds-display').setDisplaySetting('daylight-type', daylightType[0]);
            }
            if (isChanged) {
                if (_syn.liveVersion <= 0 && _nonliveCache.isEmpty()) {
                    _syn.nonliveWaitToDraw = true;
                } else {
                    _drawNonlive();
                }
            }
            if (!isChanged) {
                _drawNonlive();
            }
            _syn.nonliveDrawing = false;
        }
    };

    function _submitLive() {
        var sb = [];
        sb.push('odds-display/favourite-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=0&v=');
        sb.push(_syn.liveVersion);
        sb.push($M('more').getMoreParam(true));
        return TiLib.Ajax.sendRequest('favourite-double-live', sb.join(''));
    }

    function _submitNonlive() {
        var sb = [];
        sb.push('odds-display/favourite-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=1&v=');
        sb.push(_syn.nonliveVersion);
        sb.push('&dl=');
        sb.push($M('odds-display').getDisplaySetting('daylight-type'));
        sb.push($M('more').getMoreParam(false));
        return TiLib.Ajax.sendRequest('favourite-double-nonlive', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.liveCooldownCount) {
            _syn.liveCooldownCount--;
        } else if (_syn.liveDrawing) {
            if (_syn.liveFailureCount > 3) {
                _syn.liveDrawing = false;
            } else {
                _syn.liveFailureCount++;
            }
        } else if (_syn.liveRefreshCount > 0) {
            _drawRefreshButtons('live');
            _syn.liveRefreshCount--;
        } else {
            _syn.liveRefreshCount = _syn.liveRefreshRate;
            _syn.liveCooldownCount = 2;
            _syn.liveDrawing = true;
            _syn.liveFailureCount = 0;
            _submitLive();
            _drawRefreshButtons('live');
        }
        if (_syn.nonliveCooldownCount) {
            _syn.nonliveCooldownCount--;
        } else if (_syn.nonliveDrawing) {
            if (_syn.nonliveFailureCount > 3) {
                _syn.nonliveDrawing = false;
            } else {
                _syn.nonliveFailureCount++;
            }
        } else if (_syn.nonliveRefreshCount > 0) {
            _drawRefreshButtons('nonlive');
            _syn.nonliveRefreshCount--;
        } else {
            _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
            _syn.nonliveCooldownCount = 2;
            _syn.nonliveDrawing = true;
            _syn.nonliveFailureCount = 0;
            _submitNonlive();
            _drawRefreshButtons('nonlive');
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('live');
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('nonlive');
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('live');
                        }, 200);
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('nonlive');
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onClick = function (event) {
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    }

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'od') {
                switch (atom[2]) {
                case 'fav':
                    if (count >= 4) {
                        if (atom[3] == 'add-tournament') {
                            var eventResults = _liveCache.getEventResultIdsByTournament(parseInt(atom[4]));
                            var nonLiveEvetnResults = _nonliveCache.getEventResultIdsByTournament(parseInt(atom[4]));
                            var allEventResults = [];
                            if (eventResults) {
                                allEventResults = eventResults;
                            }
                            if (nonLiveEvetnResults) {
                                allEventResults = allEventResults.concat(nonLiveEvetnResults);
                            }
                            $M('favourite').addRemoveFavourite(atom[3], allEventResults, atom[4]);
                        } else {
                            $M('favourite').addRemoveFavourite(atom[3], atom[4]);
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.liveVersion = 0;
            _syn.nonliveVersion = 0;
        } else if (_syn.liveDrawing || _syn.nonliveDrawing || _syn.liveCooldownCount || _syn.nonliveCooldownCount) {
            return;
        }
        _syn.liveRefreshCount = _syn.liveRefreshRate;
        _syn.liveCooldownCount = 2;
        _syn.liveDrawing = true;
        _syn.liveFailureCount = 0;
        _submitLive();
        _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
        _syn.nonliveCooldownCount = 2;
        _syn.nonliveDrawing = true;
        _syn.nonliveFailureCount = 0;
        _submitNonlive();
        _drawRefreshButtons();
    };
    this.refreshLive = function (clearAll) {
        if (!_syn.liveCooldownCount) {
            if (_syn.liveDrawing) {
                if (_syn.liveFailureCount > 3) {
                    _syn.liveDrawing = false;
                } else {
                    _syn.liveFailureCount++;
                }
            } else {
                if (clearAll) _syn.liveVersion = 0;
                _syn.liveRefreshCount = _syn.liveRefreshRate;
                _syn.liveCooldownCount = 2;
                _syn.liveDrawing = true;
                _syn.liveFailureCount = 0;
                _submitLive();
                _drawRefreshButtons('live');
            }
        }
    };
    this.refreshNonlive = function (clearAll) {
        if (!_syn.nonliveCooldownCount || clearAll) {
            if (_syn.nonliveDrawing && !clearAll) {
                if (_syn.nonliveFailureCount > 3) {
                    _syn.nonliveDrawing = false;
                } else {
                    _syn.nonliveFailureCount++;
                }
            } else {
                if (clearAll) _syn.nonliveVersion = 0;
                _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
                _syn.nonliveCooldownCount = 2;
                _syn.nonliveDrawing = true;
                _syn.nonliveFailureCount = 0;
                _submitNonlive();
                _drawRefreshButtons('nonlive');
            }
        }
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _liveCache.sort(sortType);
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_templateFavourite) {
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        if (!_templateLive) {
            _syn.liveWaitingTemplate = true;
            return;
        }
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        _populateNonliveSection(d);
        var div = document.getElementById('module-odds-display');
        if (div) {
            div.innerHTML = _templateLive['odds-display'].getText(d);
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
        div = document.getElementById('bu:od:select-tournament:0');
        if (div) {
            div.parentNode.removeChild(div);
        }
        div = document.getElementById('bu:od:select-tournament:1');
        if (div) {
            div.parentNode.removeChild(div);
        }
    }

    function _drawLive() {
        if (!_templateLive || !_templateFavourite) {
            _syn.liveWaitingTemplate = true;
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        var div = document.getElementById('odds-display-live');
        if (div) {
            div.innerHTML = d['odds-display-live'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _templateLive['odds-display'].getText(d);
            }
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
        div = document.getElementById('bu:od:select-tournament:0');
        if (div) {
            div.parentNode.removeChild(div);
        }
    }

    function _drawNonlive() {
        if (!_templateNonlive || !_templateFavourite) {
            _syn.nonliveWaitingTemplate = true;
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        _populateNonliveSection(d);
        var div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.innerHTML = d['odds-display-nonlive'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _templateNonlive['odds-display'].getText(d);
            }
        }
        div = document.getElementById('bu:od:select-tournament:1');
        if (div) {
            div.parentNode.removeChild(div);
        }
    }

    function _drawLoading() {
        if (_syn.liveVersion == 0 && _syn.nonliveVersion == 0 && _liveCache.isEmpty() && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_templateLive && _templateLive['loading']) {
                    text = _templateLive['loading'].getText();
                } else if (_templateNonlive && _templateNonlive['loading']) {
                    text = _templateNonlive['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _populateLiveSection(d) {
        $M('odds-display').clearRef();
        var template = _templateLive;
        var favTemplate = _templateFavourite;
        var cache = _liveCache;
        var favCache = $M('favourite').getCache();
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var marketGroupId = 0;
        var favourite;
        var showMarketGroups = $M('odds-display').getDisplaySetting('market-showing') == 2 ? true : false;
        var selectedOddId = $M('ticket').getOddIdOption();
        d['market-page'] = template['market-page-favourite'].getText();
        d['live-ext'] = template['live-ext'].getText();
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var marketGroup = tagEventResult[6];
            if (marketGroup && marketGroup[0] != 0 && !showMarketGroups) {
                continue;
            }
            if (!favCache.hasEventResult(eventResultId) && !favCache.hasTournament(tournament[0])) {
                continue;
            }
            var oddsFTime1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTime1X2] : null;
            var oddsFHalf1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalf1X2] : null;
            var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
            var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
            var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
            var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
            var oddsFTimeLS = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeLS] : null;
            var rowCount = 0;
            if (oddsFTime1X2 && rowCount < oddsFTime1X2.length) {
                rowCount = oddsFTime1X2.length;
            }
            if (oddsFHalf1X2 && rowCount < oddsFHalf1X2.length) {
                rowCount = oddsFHalf1X2.length;
            }
            if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
                rowCount = oddsFTimeHDP.length;
            }
            if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
                rowCount = oddsFHalfHDP.length;
            }
            if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
                rowCount = oddsFTimeOU.length;
            }
            if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
                rowCount = oddsFHalfOU.length;
            }
            if (oddsFTimeLS && rowCount < oddsFTimeLS.length) {
                rowCount = oddsFTimeLS.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                var frozenOdds = eventResultExtra[8];
                var count = null;
                if (frozenOdds) {
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeHDP]) ? 0 : frozenOdds[_MarketDisplay.FTimeHDP];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalfHDP]) ? 0 : frozenOdds[_MarketDisplay.FHalfHDP];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeOU]) ? 0 : frozenOdds[_MarketDisplay.FTimeOU];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalfOU]) ? 0 : frozenOdds[_MarketDisplay.FHalfOU];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FTime1X2]) ? 0 : frozenOdds[_MarketDisplay.FTime1X2];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalf1X2]) ? 0 : frozenOdds[_MarketDisplay.FHalf1X2];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeLS]) ? 0 : frozenOdds[_MarketDisplay.FTimeLS];
                    rowCount = Math.max(rowCount, count);
                    rowCount = rowCount > 1 ? 1 : rowCount;
                }
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                marketGroupId = 0;
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                if (favCache.hasTournament(tournamentId)) {
                    favourite = 'icon-nonlive-tournament-remove';
                } else {
                    favourite = 'icon-nonlive-tournament-add';
                }
                d['icon-favourite-tournament'] = favTemplate[favourite].getText(d);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasLiveVideo(eventId) ? template['icon-video'].getText(d) : null;
            d['ls-class'] = '';
            d['ls-tooltip'] = '';
            d['ls-id'] = 0;
            if (_mediaCache.hasLiveCenter(eventId)) {
                d['ls-class'] = 'ls-time-column';
                d['ls-tooltip'] = template['ls-tooltip'].getText();
                d['ls-id'] = d['event-id'];
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['home-score'] = eventResult[3];
            d['away-score'] = eventResult[4];
            d['score-separator'] = template['score-separator'].getText(d);
            d['draw'] = template['draw'].getText();
            d['vs'] = template['vs'].getText();
            d['score-class'] = cache.isScoreChanged(eventResultId) ? 'score-change' : '';
            var moreContent = '';
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 0)) {
                moreContent = $M('more').getContent(11);
            } else if ($M('more').isClosing(eventResultId, 0)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = showMarketGroups ? cache.getEventResultMoreOddsCount(eventResultId) : cache.getEventMoreOddsCount(eventResultId);
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            if (marketGroup && marketGroup[0]) {
                OddsUtility.populateMarketGroup(d, marketGroup);
                OddsUtility.populateMarketGroupTeams(d, marketGroup);
                if (marketGroupId != marketGroup[0]) {
                    marketGroupId = marketGroup[0];
                    rows.push(template['row-market-group'].getText(d));
                }
                d['icon-statistics'] = '';
                d['icon-video'] = '';
            } else {
                marketGroupId = 0;
            }
            favourite = 'icon-live-event-remove';
            d['icon-favourite-event'] = favTemplate[favourite].getText(d);
            d['live-time'] = template['time-live'].getText(d);
            if (eventResultExtra) {
                var period = eventResultExtra[2];
                if (period > 0) {
                    if (period == 5) {
                        d['live-time'] = template['time-halftime'].getText(d);
                    } else {
                        d['live-time'] = OddsUtility.getLiveTime(period, cache.getLiveStartTime(eventResultId), eventResultExtra[3], eventResultExtra[4]);
                        var injuryTime = parseInt('' + eventResultExtra[7], 10);
                        if (injuryTime && injuryTime > 0) {
                            d['injuryTimeCount'] = injuryTime;
                            d['live-time'] += template['injury-time'].getText(d);
                        }
                    }
                }
            }
            var homeRedCards = '';
            var awayRedCards = '';
            if (eventResultExtra) {
                var redCardIndex;
                var redCardCount = eventResultExtra[5];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        homeRedCards += template['red-card'].getText(d);
                    }
                }
                redCardCount = eventResultExtra[6];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        awayRedCards += template['red-card'].getText(d);
                    }
                }
            }
            d['home-red-cards'] = homeRedCards;
            d['away-red-cards'] = awayRedCards;
            d['sub-row'] = '';
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                var has1X2 = false;
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['home-color-class'] = hdp > 0 ? 'Red' : 'Blue';
                d['away-color-class'] = hdp < 0 ? 'Red' : 'Blue';
                odds = oddsFTime1X2 ? oddsFTime1X2[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTime1X2);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTime1X2);
                }
                odds = oddsFHalf1X2 ? oddsFHalf1X2[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalf1X2);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalf1X2);
                }
                odds = oddsFTimeLS ? oddsFTimeLS[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeLS);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeLS);
                }
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeHDP);
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfHDP);
                }
                odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOU);
                }
                odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOU);
                }
                d['row-index'] = oddsRowIndex;
                var rowTemplateName;
                if (marketGroup && marketGroup[5]) {
                    rowTemplateName = 'row-event-yesno';
                    if (has1X2) {
                        rowTemplateName = 'row-event-yesno-1x2';
                    }
                } else if (!has1X2 && template['row-event-no1x2']) {
                    rowTemplateName = 'row-event-no1x2';
                } else {
                    rowTemplateName = 'row-event';
                }
                d['bg-color'] = (templateRowIndex & 1) ? '#FFDDCC' : '#FFDDCC';
                rows.push(template[rowTemplateName].getText(d));
                oddsRowIndex++;
                d['icon-statistics'] = null;
                d['icon-video'] = null;
                d['ls-class'] = '';
                d['ls-id'] = 0;
                d['ls-tooltip'] = '';
                d['home-score'] = null;
                d['away-score'] = null;
                d['score-separator'] = null;
                d['draw'] = null;
                d['vs'] = null;
                d['score-class'] = null;
                d['icon-more'] = null;
                d['live-time'] = null;
                d['home-red-cards'] = null;
                d['away-red-cards'] = null;
                d['original-home'] = null;
                d['original-away'] = null;
                d['home'] = null;
                d['away'] = null;
                d['tv-channel'] = null;
                d['sub-row'] = 'subrow';
                d['icon-favourite-event'] = null;
            }
            rows.push(moreContent);
            templateRowIndex++;
        }
        var ret = 0;
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['refresh-count'] = _syn.liveRefreshCount;
            d['refresh-button'] = _syn.liveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
            d['additional-class'] = _getAdditionalClass();
            d['table'] = template['table'].getText(d);
            d['odds-display-live'] = template['odds-display-live'].getText(d);
            ret = rows.length;
        } else if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
            _drawLoading();
            ret = 0;
        } else {
            d['odds-display-live'] = '';
            ret = 0;
        }
        return ret;
    }

    function _getAdditionalClass() {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        switch (parseInt(sportId)) {
        case 2:
            return _templateLive['basketball-additional-class'].getText();
        default:
            return '';
        }
    }

    function _populateDaylightType(d) {
        var daylightType = $M('odds-display').getDisplaySetting('daylight-type');
        if (_daylightPeriod) {
            $M('odds-display-setting').draw();
        }
    }

    function _populateNonliveSection(d) {
        $M('odds-display').clearRef();
        var template = _templateNonlive;
        var favTemplate = _templateFavourite;
        var cache = _nonliveCache;
        var favCache = $M('favourite').getCache();
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var selectedOddId = $M('ticket').getOddIdOption();
        d['market-page'] = template['market-page-favourite'].getText();
        d['nonlive-ext'] = template['nonlive-ext'].getText();
        d['sport-id'] = $M('odds-display').getDisplaySetting('sport');
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        var sportId = $M('odds-display').getDisplaySetting('sport');
        var colSpan = _NonliveColSpan[sportId];
        if (!colSpan) colSpan = _NonliveColSpan[7];
        if (sportId == 1) {
            _populateDaylightType(d);
        }
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var oddsFTime1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTime1X2] : null;
            var oddsFHalf1X2 = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalf1X2] : null;
            var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
            var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
            var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
            var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
            var oddsML = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.ML] : null;
            var oddsFTimeOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOE] : null;
            var oddsFHalfOE = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOE] : null;
            if (!favCache.hasEventResult(eventResultId) && !favCache.hasTournament(tournament[0])) {
                continue;
            }
            var rowCount = 0;
            if (oddsFTime1X2 && rowCount < oddsFTime1X2.length) {
                rowCount = oddsFTime1X2.length;
            }
            if (oddsFHalf1X2 && rowCount < oddsFHalf1X2.length) {
                rowCount = oddsFHalf1X2.length;
            }
            if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
                rowCount = oddsFTimeHDP.length;
            }
            if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
                rowCount = oddsFHalfHDP.length;
            }
            if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
                rowCount = oddsFTimeOU.length;
            }
            if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
                rowCount = oddsFHalfOU.length;
            }
            if (oddsML && rowCount < oddsML.length) {
                rowCount = oddsML.length;
            }
            if (oddsFTimeOE && rowCount < oddsFTimeOE.length) {
                rowCount = oddsFTimeOE.length;
            }
            if (oddsFHalfOE && rowCount < oddsFHalfOE.length) {
                rowCount = oddsFHalfOE.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                rowCount = 1;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                if (favCache.hasTournament(tournamentId)) {
                    favourite = 'icon-nonlive-tournament-remove';
                } else {
                    favourite = 'icon-nonlive-tournament-add';
                }
                d['icon-favourite-tournament'] = favTemplate[favourite].getText(d);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = template['showtime-date-time'].getText(d);
            }
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? template['icon-video-nonlive'].getText(d) : '';
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['draw'] = template['draw'].getText();
            var moreContent = '';
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 1)) {
                moreContent = $M('more').getContent(colSpan);
            } else if ($M('more').isClosing(eventResultId, 1)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = cache.getEventMoreOddsCount(eventResultId);
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            d['sub-row'] = '';
            favourite = 'icon-nonlive-event-remove';
            d['icon-favourite-event'] = favTemplate[favourite].getText(d);
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                var has1X2 = false;
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['home-color-class'] = hdp > 0 ? 'Red' : 'Blue';
                d['away-color-class'] = hdp < 0 ? 'Red' : 'Blue';
                odds = oddsFTime1X2 ? oddsFTime1X2[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTime1X2);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTime1X2);
                }
                odds = oddsFHalf1X2 ? oddsFHalf1X2[rowIndex] : null;
                if (odds) {
                    has1X2 = true;
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalf1X2);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalf1X2);
                }
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeHDP);
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfHDP);
                }
                odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOU);
                }
                odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOU);
                }
                odds = oddsML ? oddsML[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.ML);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.ML);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.ML);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.ML);
                }
                odds = oddsFTimeOE ? oddsFTimeOE[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOE);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOE);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOE);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOE);
                }
                odds = oddsFHalfOE ? oddsFHalfOE[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOE);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOE);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOE);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOE);
                }
                d['row-index'] = oddsRowIndex;
                oddsRowIndex++;
                rows.push(template[(templateRowIndex & 1) ? 'row-event-alt' : 'row-event'].getText(d));
                d['icon-video'] = null;
                d['icon-statistics'] = null;
                d['showtime'] = null;
                d['live-time'] = null;
                d['home'] = null;
                d['away'] = null;
                d['draw'] = null;
                d['icon-more'] = null;
                d['sub-row'] = 'subrow';
                d['icon-favourite-event'] = null;
            }
            rows.push(moreContent);
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.nonliveRefreshCount;
        d['refresh-button'] = _syn.nonliveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        } else if (cache.isEmpty() && _syn.nonliveVersion == 0) {
            _drawLoading();
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        }
    }

    function _drawRefreshButtons(section) {
        if (!_templateLive) {
            _syn.livewaitingtemplate = true;
            return;
        }
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        if (section === undefined || section == 'live') {
            var a = document.getElementById('bu:od:refresh-live:button');
            if (a) {
                if (_syn.liveCooldownCount) {
                    a.innerHTML = _templateLive['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _templateLive['refresh'].getText();
                } else {
                    a.innerHTML = _templateLive['refresh-countdown'].getText({
                        'refresh-count': _syn.liveRefreshCount
                    });
                }
            }
        }
        if (section === undefined || section == 'nonlive') {
            a = document.getElementById('bu:od:refresh-nonlive:button');
            if (a) {
                if (_syn.nonliveCooldownCount) {
                    a.innerHTML = _templateNonlive['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _templateNonlive['refresh'].getText();
                } else {
                    a.innerHTML = _templateNonlive['refresh-countdown'].getText({
                        'refresh-count': _syn.nonliveRefreshCount
                    });
                }
            }
        }
    }
}

function __Module_FavouriteSingle(refreshRate, sortType) {
    var _MarketDisplay = {
        FTime1X2: 5,
        FHalf1X2: 8,
        FTimeHDP: 1,
        FHalfHDP: 7,
        FTimeOU: 3,
        FHalfOU: 9,
        FTimeOE: 2,
        ML: 11
    };
    var _TemplateNameLive = 'odds-display/today-single-live';
    var _TemplateNameNonlive = 'odds-display/today-single-nonlive';
    var _TemplateNameFavourite = 'left-column/favourite';
    var _self = this;
    var _templateLive = null;
    var _templateNonlive = null;
    var _templateFavourite = null;
    var _liveCache = new __Cache_Event(sortType);
    var _nonliveCache = new __Cache_Event(sortType);
    var _mediaCache = new __Cache_Media();
    var _daylightPeriod = 0;
    var _syn = {
        liveWaitingTemplate: false,
        liveDrawing: false,
        liveRefreshRate: refreshRate[0],
        liveRefreshCount: 0,
        liveCooldownCount: 0,
        liveFailureCount: 0,
        liveVersion: 0,
        nonliveWaitingTemplate: false,
        nonliveDrawing: false,
        nonliveRefreshRate: refreshRate[1],
        nonliveRefreshCount: 0,
        nonliveCooldownCount: 0,
        nonliveFailureCount: 0,
        nonliveVersion: 0,
        nonliveWaitToDraw: false,
        favouriteWaitingTemplate: false
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateNameLive);
        if (templateText) {
            _templateLive = TiLib.Template.createTemplates(templateText);
        }
        templateText = $P.getTemplate(_TemplateNameNonlive);
        if (templateText) {
            _templateNonlive = TiLib.Template.createTemplates(templateText);
        }
        templateText = $P.getTemplate(_TemplateNameFavourite);
        if (templateText) {
            _templateFavourite = TiLib.Template.createTemplates(templateText);
        }
        if (_templateNonlive || _templateLive || _templateFavourite) {
            _drawLoading();
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateNameLive) {
            var templateText = $P.getTemplate(_TemplateNameLive);
            if (templateText) {
                _templateLive = TiLib.Template.createTemplates(templateText);
                if (_templateLive) {
                    if (_syn.liveWaitingTemplate) {
                        _syn.liveWaitingTemplate = false;
                        _drawLive();
                    }
                    if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
        if (name == _TemplateNameNonlive) {
            var templateText = $P.getTemplate(_TemplateNameNonlive);
            if (templateText) {
                _templateNonlive = TiLib.Template.createTemplates(templateText);
                if (_templateNonlive) {
                    if (_syn.nonliveWaitingTemplate) {
                        _syn.nonliveWaitingTemplate = false;
                        _drawNonlive();
                    }
                    if (_syn.nonliveVersion == 0 && _nonliveCache.isEmpty()) {
                        _drawLoading();
                    }
                }
            }
        }
        if (name == _TemplateNameFavourite) {
            var templateText = $P.getTemplate(_TemplateNameFavourite);
            if (templateText) {
                _templateFavourite = TiLib.Template.createTemplates(templateText);
                if (_templateFavourite) {
                    if (_syn.favouriteWaitingTemplate) {
                        _syn.favouriteWaitingTemplate = false;
                        if (!_syn.liveDrawing && !_syn.nonliveDrawing) {
                            _drawLive();
                            _drawNonlive();
                        }
                    }
                }
            }
        }
    };
    this.onIdle = function (data) {
        var version = data[0];
        var frameIndex = data[1];
        if (frameIndex == 0) {
            if (_syn.liveVersion < version) {
                _syn.liveVersion = version;
            }
            _liveCache.clearAdjustIndicators();
            _drawLive();
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
            }
            _nonliveCache.clearAdjustIndicators();
            _drawNonlive();
            _syn.nonliveDrawing = false;
        }
    };
    this.onUpdate = function (data) {
        if (!data) return;
        var version = data[0];
        var frameIndex = data[1];
        var clearAll = data[2];
        var frameData = data[3];
        var mediaData = data[4];
        var daylightType = data[5];
        var favouriteCacheData = data[6];
        var isChanged = false;
        if (frameIndex == 0) {
            if (_liveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.liveVersion < version) {
                _syn.liveVersion = version;
                if (_liveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (favouriteCacheData) {
                $M('favourite').onUpdate(favouriteCacheData);
            }
            if (isChanged) {
                _drawLive();
                if (_syn.nonliveWaitToDraw) {
                    _syn.nonliveWaitToDraw = false;
                    _drawNonlive();
                }
            }
            if (!isChanged) {
                _drawLive();
            }
            _syn.liveDrawing = false;
        } else if (frameIndex == 1) {
            if (_nonliveCache.clearAdjustIndicators()) {
                isChanged = true;
            }
            if (clearAll || _syn.nonliveVersion < version) {
                _syn.nonliveVersion = version;
                if (_nonliveCache.update(clearAll, frameData, $M('odds-display').getDisplaySetting('price-style'))) {
                    isChanged = true;
                }
            }
            if (_mediaCache.update(mediaData)) {
                isChanged = true;
            }
            if (favouriteCacheData) {
                $M('favourite').onUpdate(favouriteCacheData);
            }
            if (daylightType && daylightType.length >= 2) {
                _daylightPeriod = daylightType[1];
                $M('odds-display').setDisplaySetting('daylight-type-period', daylightType[1]);
                $M('odds-display').setDisplaySetting('daylight-type', daylightType[0]);
            }
            if (isChanged) {
                if (_syn.liveVersion <= 0 && _nonliveCache.isEmpty()) {
                    _syn.nonliveWaitToDraw = true;
                } else {
                    _drawNonlive();
                }
            }
            if (!isChanged) {
                _drawNonlive();
            }
            _syn.nonliveDrawing = false;
        }
    };

    function _submitLive() {
        var sb = [];
        sb.push('odds-display/favourite-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=0&v=');
        sb.push(_syn.liveVersion);
        sb.push($M('more').getMoreParam(true));
        return TiLib.Ajax.sendRequest('today-single-live', sb.join(''));
    }

    function _submitNonlive() {
        var sb = [];
        sb.push('odds-display/favourite-data.aspx?od-param=');
        sb.push($M('odds-display').getOddsDisplayParam());
        sb.push('&fi=1&v=');
        sb.push(_syn.nonliveVersion);
        sb.push('&dl=');
        sb.push($M('odds-display').getDisplaySetting('daylight-type'));
        sb.push($M('more').getMoreParam(false));
        return TiLib.Ajax.sendRequest('today-single-nonlive', sb.join(''));
    }
    this.onTime = function () {
        if (_syn.liveCooldownCount) {
            _syn.liveCooldownCount--;
        } else if (_syn.liveDrawing) {
            if (_syn.liveFailureCount > 3) {
                _syn.liveDrawing = false;
            } else {
                _syn.liveFailureCount++;
            }
        } else if (_syn.liveRefreshCount > 0) {
            _drawRefreshButtons('live');
            _syn.liveRefreshCount--;
        } else {
            _syn.liveRefreshCount = _syn.liveRefreshRate;
            _syn.liveCooldownCount = 2;
            _syn.liveDrawing = true;
            _syn.liveFailureCount = 0;
            _submitLive();
            _drawRefreshButtons('live');
        }
        if (_syn.nonliveCooldownCount) {
            _syn.nonliveCooldownCount--;
        } else if (_syn.nonliveDrawing) {
            if (_syn.nonliveFailureCount > 3) {
                _syn.nonliveDrawing = false;
            } else {
                _syn.nonliveFailureCount++;
            }
        } else if (_syn.nonliveRefreshCount > 0) {
            _drawRefreshButtons('nonlive');
            _syn.nonliveRefreshCount--;
        } else {
            _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
            _syn.nonliveCooldownCount = 2;
            _syn.nonliveDrawing = true;
            _syn.nonliveFailureCount = 0;
            _submitNonlive();
            _drawRefreshButtons('nonlive');
        }
    };
    this.onMouseOver = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('live');
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (!e.isHover) {
                        e.isHover = true;
                        _drawRefreshButtons('nonlive');
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name == 'refresh-button') {
            var e = event.srcElement ? event.srcElement : event.target;
            while (e) {
                switch (e.id) {
                case 'bu:od:refresh-live:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('live');
                        }, 200);
                    }
                    return false;
                case 'bu:od:refresh-nonlive:button':
                    if (e.isHover) {
                        e.isHover = false;
                        setTimeout(function () {
                            _drawRefreshButtons('nonlive');
                        }, 200);
                    }
                    return false;
                }
                e = e.parentNode;
            }
        }
        return true;
    };
    this.onClick = function (event) {
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    }

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'od') {
                switch (atom[2]) {
                case 'fav':
                    if (count >= 4) {
                        if (atom[3] == 'add-tournament') {
                            var eventResults = _liveCache.getEventResultIdsByTournament(parseInt(atom[4]));
                            var nonLiveEvetnResults = _nonliveCache.getEventResultIdsByTournament(parseInt(atom[4]));
                            var allEventResults = [];
                            if (eventResults) {
                                allEventResults = eventResults;
                            }
                            if (nonLiveEvetnResults) {
                                allEventResults = allEventResults.concat(nonLiveEvetnResults);
                            }
                            $M('favourite').addRemoveFavourite(atom[3], allEventResults, atom[4]);
                        } else {
                            $M('favourite').addRemoveFavourite(atom[3], atom[4]);
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }
    this.refresh = function (clearAll) {
        if (clearAll) {
            _syn.liveVersion = 0;
            _syn.nonliveVersion = 0;
        } else if (_syn.liveDrawing || _syn.nonliveDrawing || _syn.liveCooldownCount || _syn.nonliveCooldownCount) {
            return;
        }
        _syn.liveRefreshCount = _syn.liveRefreshRate;
        _syn.liveCooldownCount = 2;
        _syn.liveDrawing = true;
        _syn.liveFailureCount = 0;
        _submitLive();
        _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
        _syn.nonliveCooldownCount = 2;
        _syn.nonliveDrawing = true;
        _syn.nonliveFailureCount = 0;
        _submitNonlive();
        _drawRefreshButtons();
    };
    this.refreshLive = function (clearAll) {
        if (!_syn.liveCooldownCount) {
            if (_syn.liveDrawing) {
                if (_syn.liveFailureCount > 3) {
                    _syn.liveDrawing = false;
                } else {
                    _syn.liveFailureCount++;
                }
            } else {
                if (clearAll) _syn.liveVersion = 0;
                _syn.liveRefreshCount = _syn.liveRefreshRate;
                _syn.liveCooldownCount = 2;
                _syn.liveDrawing = true;
                _syn.liveFailureCount = 0;
                _submitLive();
                _drawRefreshButtons('live');
            }
        }
    };
    this.refreshNonlive = function (clearAll) {
        if (!_syn.nonliveCooldownCount || clearAll) {
            if (_syn.nonliveDrawing && !clearAll) {
                if (_syn.nonliveFailureCount > 3) {
                    _syn.nonliveDrawing = false;
                } else {
                    _syn.nonliveFailureCount++;
                }
            } else {
                if (clearAll) _syn.nonliveVersion = 0;
                _syn.nonliveRefreshCount = _syn.nonliveRefreshRate;
                _syn.nonliveCooldownCount = 2;
                _syn.nonliveDrawing = true;
                _syn.nonliveFailureCount = 0;
                _submitNonlive();
                _drawRefreshButtons('nonlive');
            }
        }
    };
    this.sort = function () {
        var sortType = $M('odds-display').getDisplaySetting('sorting');
        _liveCache.sort(sortType);
        _nonliveCache.sort(sortType);
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_templateLive) {
            _syn.liveWaitingTemplate = true;
            return;
        }
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        if (!_templateFavourite) {
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        _populateNonliveSection(d);
        var div = document.getElementById('module-odds-display');
        if (div) {
            div.innerHTML = _templateLive['odds-display'].getText(d);
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
        div = document.getElementById('bu:od:select-tournament:0');
        if (div) {
            div.parentNode.removeChild(div);
        }
        div = document.getElementById('bu:od:select-tournament:1');
        if (div) {
            div.parentNode.removeChild(div);
        }
    }

    function _drawLive() {
        if (!_templateLive || !_templateFavourite) {
            _syn.liveWaitingTemplate = true;
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        var hasLive = _populateLiveSection(d);
        var div = document.getElementById('odds-display-live');
        if (div) {
            div.innerHTML = d['odds-display-live'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _templateLive['odds-display'].getText(d);
            }
        }
        div = document.getElementById('odds-display-live');
        if (div) {
            if (!hasLive) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            }
        }
        div = document.getElementById('bu:od:select-tournament:0');
        if (div) {
            div.parentNode.removeChild(div);
        }
    }

    function _drawNonlive() {
        if (!_templateNonlive || !_templateFavourite) {
            _syn.nonliveWaitingTemplate = true;
            _syn.favouriteWaitingTemplate = true;
            return;
        }
        var d = {};
        _populateNonliveSection(d);
        var div = document.getElementById('odds-display-nonlive');
        if (div) {
            div.innerHTML = d['odds-display-nonlive'];
        } else {
            div = document.getElementById('module-odds-display');
            if (div) {
                div.innerHTML = _templateNonlive['odds-display'].getText(d);
            }
        }
        div = document.getElementById('bu:od:select-tournament:1');
        if (div) {
            div.parentNode.removeChild(div);
        }
    }

    function _drawLoading() {
        if (_syn.liveVersion == 0 && _syn.nonliveVersion == 0 && _liveCache.isEmpty() && _nonliveCache.isEmpty()) {
            var div = document.getElementById('module-odds-display');
            if (div) {
                var text = '';
                if (_templateLive && _templateLive['loading']) {
                    text = _templateLive['loading'].getText();
                } else if (_templateNonlive && _templateNonlive['loading']) {
                    text = _templateNonlive['loading'].getText();
                } else {
                    text = '<h1 align="center">Loading...</h1>';
                }
                div.innerHTML = text;
            }
        }
    }

    function _populateDaylightType(d) {
        var daylightType = $M('odds-display').getDisplaySetting('daylight-type');
        if (_daylightPeriod) {
            $M('odds-display-setting').draw();
        }
    }

    function _populateLiveSection(d) {
        $M('odds-display').clearRef();
        var template = _templateLive;
        var favTemplate = _templateFavourite;
        var cache = _liveCache;
        var favCache = $M('favourite').getCache();
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var marketGroupId = 0;
        var showMarketGroups = $M('odds-display').getDisplaySetting('market-showing') == 2 ? true : false;
        var selectedOddId = $M('ticket').getOddIdOption();
        d['market-page'] = _templateLive['market-page-favourite'].getText();
        d['live-ext'] = _templateLive['live-ext'].getText();
        var sportId = $M('odds-display').getDisplaySetting('sport');
        d['sport-id'] = sportId;
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var marketGroup = tagEventResult[6];
            if (marketGroup && marketGroup[0] != 0 && !showMarketGroups) {
                continue;
            }
            var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
            var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
            var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
            var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
            if (!favCache.hasEventResult(eventResultId) && !favCache.hasTournament(tournament[0])) {
                continue;
            }
            var rowCount = 0;
            if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
                rowCount = oddsFTimeHDP.length;
            }
            if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
                rowCount = oddsFHalfHDP.length;
            }
            if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
                rowCount = oddsFTimeOU.length;
            }
            if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
                rowCount = oddsFHalfOU.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                var frozenOdds = eventResultExtra[8];
                var count = null;
                if (frozenOdds) {
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeHDP]) ? 0 : frozenOdds[_MarketDisplay.FTimeHDP];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalfHDP]) ? 0 : frozenOdds[_MarketDisplay.FHalfHDP];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FTimeOU]) ? 0 : frozenOdds[_MarketDisplay.FTimeOU];
                    rowCount = Math.max(rowCount, count);
                    count = isNaN(frozenOdds[_MarketDisplay.FHalfOU]) ? 0 : frozenOdds[_MarketDisplay.FHalfOU];
                    rowCount = Math.max(rowCount, count);
                    rowCount = rowCount > 1 ? 1 : rowCount;
                }
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                marketGroupId = 0;
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                if (favCache.hasTournament(tournamentId)) {
                    favourite = 'icon-nonlive-tournament-remove';
                } else {
                    favourite = 'icon-nonlive-tournament-add';
                }
                d['icon-favourite-tournament'] = favTemplate[favourite].getText(d);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            d['icon-video'] = _mediaCache.hasLiveVideo(eventId) ? template['icon-video'].getText(d) : null;
            d['ls-class'] = '';
            d['ls-tooltip'] = '';
            d['ls-id'] = 0;
            if (_mediaCache.hasLiveCenter(eventId)) {
                d['ls-class'] = 'ls-time-column';
                d['ls-tooltip'] = template['ls-tooltip'].getText();
                d['ls-id'] = d['event-id'];
            }
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['home-score'] = eventResult[3];
            d['away-score'] = eventResult[4];
            d['score-separator'] = template['score-separator'].getText(d);
            d['draw'] = template['draw'].getText();
            d['vs'] = template['vs'].getText();
            d['score-class'] = cache.isScoreChanged(eventResultId) ? 'score-change' : '';
            var moreContent = '';
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 0)) {
                moreContent = $M('more').getContent(16);
            } else if ($M('more').isClosing(eventResultId, 0)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = showMarketGroups ? cache.getEventResultMoreOddsCount(eventResultId) : cache.getEventMoreOddsCount(eventResultId);
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            if (marketGroup && marketGroup[0]) {
                OddsUtility.populateMarketGroup(d, marketGroup);
                OddsUtility.populateMarketGroupTeams(d, marketGroup);
                if (marketGroupId != marketGroup[0]) {
                    marketGroupId = marketGroup[0];
                    rows.push(template['row-market-group'].getText(d));
                }
                d['icon-statistics'] = '';
                d['icon-video'] = '';
            } else {
                marketGroupId = 0;
            }
            favourite = 'icon-live-event-remove';
            d['icon-favourite-event'] = favTemplate[favourite].getText(d);
            d['live-time'] = template['time-live'].getText(d);
            if (eventResultExtra) {
                var period = eventResultExtra[2];
                if (period > 0) {
                    if (period == 5) {
                        d['live-time'] = template['time-halftime'].getText(d);
                    } else {
                        d['live-time'] = OddsUtility.getLiveTime(period, cache.getLiveStartTime(eventResultId), eventResultExtra[3], eventResultExtra[4]);
                        var injuryTime = parseInt('' + eventResultExtra[7], 10);
                        if (injuryTime && injuryTime > 0) {
                            d['injuryTimeCount'] = injuryTime;
                            d['live-time'] += template['injury-time'].getText(d);
                        }
                    }
                }
            }
            var homeRedCards = '';
            var awayRedCards = '';
            if (eventResultExtra) {
                var redCardIndex;
                var redCardCount = eventResultExtra[5];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        homeRedCards += template['red-card'].getText(d);
                    }
                }
                redCardCount = eventResultExtra[6];
                if (redCardCount) {
                    for (redCardIndex = 0; redCardIndex < redCardCount; ++redCardIndex) {
                        awayRedCards += template['red-card'].getText(d);
                    }
                }
            }
            d['home-red-cards'] = homeRedCards;
            d['away-red-cards'] = awayRedCards;
            d['sub-row'] = '';
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['home-color-class'] = hdp > 0 ? 'Red' : 'Blue';
                d['away-color-class'] = hdp < 0 ? 'Red' : 'Blue';
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeHDP);
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfHDP);
                }
                odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOU);
                }
                odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOU);
                }
                d['row-index'] = oddsRowIndex;
                var rowTemplateName = 'row-event';
                if (marketGroup && marketGroup[4] && marketGroup[5] == 1) {
                    rowTemplateName = 'row-event-yesno';
                }
                d['bg-color'] = (templateRowIndex & 1) ? '#FFDDCC' : '#FFDDCC';
                rows.push(template[rowTemplateName].getText(d));
                oddsRowIndex++;
                d['icon-statistics'] = null;
                d['icon-video'] = null;
                d['ls-class'] = '';
                d['ls-id'] = 0;
                d['ls-tooltip'] = '';
                d['home-score'] = null;
                d['away-score'] = null;
                d['score-separator'] = null;
                d['draw'] = null;
                d['vs'] = null;
                d['score-class'] = null;
                d['icon-more'] = null;
                d['live-time'] = null;
                d['home-red-cards'] = null;
                d['away-red-cards'] = null;
                d['original-home'] = null;
                d['original-away'] = null;
                d['home'] = null;
                d['away'] = null;
                d['tv-channel'] = null;
                d['sub-row'] = 'subrow';
                d['icon-favourite-event'] = null;
            }
            rows.push(moreContent);
            templateRowIndex++;
        }
        var ret = 0;
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['refresh-count'] = _syn.liveRefreshCount;
            d['refresh-button'] = _syn.liveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
            d['additional-class'] = _getAdditionalClass();
            d['table'] = template['table'].getText(d);
            d['odds-display-live'] = template['odds-display-live'].getText(d);
            ret = rows.length;
        } else if (_syn.liveVersion == 0 && _liveCache.isEmpty()) {
            _drawLoading();
            ret = 0;
        } else {
            d['odds-display-live'] = '';
            ret = 0;
        }
        return ret;
    }

    function _populateNonliveSection(d) {
        $M('odds-display').clearRef();
        var template = _templateNonlive;
        var favTemplate = _templateFavourite;
        var cache = _nonliveCache;
        var favCache = $M('favourite').getCache();
        var usesLocalTime = $M('odds-display').getDisplaySetting('display-in-local-time');
        var tagEventResults = cache.getTagEventResultArray();
        var c = tagEventResults.length;
        var rows = [];
        var oddsRowIndex = 0;
        var templateRowIndex = 0;
        var tournamentId = 0;
        var selectedOddId = $M('ticket').getOddIdOption();
        d['market-page'] = template['market-page-favourite'].getText();
        d['nonlive-ext'] = template['nonlive-ext'].getText();
        var sportId = $M('odds-display').getDisplaySetting('sport');
        d['sport-id'] = sportId;
        d['sport'] = TiLib.Text.encodeHTML(cache.getSportName());
        if (sportId == 1) _populateDaylightType(d);
        var limitedRow = $M('odds-display').getDisplaySetting('limited-rows');
        for (var i = 0; i < c; ++i) {
            var tagEventResult = tagEventResults[i];
            var tournament = tagEventResult[1];
            var event = tagEventResult[2];
            var eventId = event[0];
            var eventResult = tagEventResult[3];
            var eventResultId = eventResult[0];
            var eventResultExtra = tagEventResult[4];
            var oddsByMarketDisplayId = tagEventResult[5];
            var oddsFTimeHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeHDP] : null;
            var oddsFHalfHDP = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfHDP] : null;
            var oddsFTimeOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FTimeOU] : null;
            var oddsFHalfOU = oddsByMarketDisplayId ? oddsByMarketDisplayId[_MarketDisplay.FHalfOU] : null;
            if (!favCache.hasEventResult(eventResultId) && !favCache.hasTournament(tournament[0])) {
                continue;
            }
            var rowCount = 0;
            if (oddsFTimeHDP && rowCount < oddsFTimeHDP.length) {
                rowCount = oddsFTimeHDP.length;
            }
            if (oddsFHalfHDP && rowCount < oddsFHalfHDP.length) {
                rowCount = oddsFHalfHDP.length;
            }
            if (oddsFTimeOU && rowCount < oddsFTimeOU.length) {
                rowCount = oddsFTimeOU.length;
            }
            if (oddsFHalfOU && rowCount < oddsFHalfOU.length) {
                rowCount = oddsFHalfOU.length;
            }
            if (rowCount == 0 && eventResultExtra && rowCount < eventResultExtra[1]) {
                rowCount = 1;
            }
            if (rowCount <= 0) {
                continue;
            }
            if (tournamentId != tournament[0]) {
                tournamentId = tournament[0];
                OddsUtility.populateTournament(d, tournament);
                OddsUtility.populateTournamentInfo(d, tournament, template['tournament-info']);
                if (favCache.hasTournament(tournamentId)) {
                    favourite = 'icon-nonlive-tournament-remove';
                } else {
                    favourite = 'icon-nonlive-tournament-add';
                }
                d['icon-favourite-tournament'] = favTemplate[favourite].getText(d);
                rows.push(template['row-tournament'].getText(d));
            }
            OddsUtility.populateEvent(d, event);
            OddsUtility.populateShowTime(d, event[7], usesLocalTime);
            var showTimeType = event[6];
            if (showTimeType & 0x8) {
                d['showtime'] = template['showtime-blue-live'].getText(d);
            } else if (showTimeType & 0x4) {
                d['showtime'] = template['showtime-red-live'].getText(d);
            } else if (showTimeType & 0x2) {
                d['showtime'] = template['showtime-date-time'].getText(d);
            } else if (showTimeType & 0x1) {
                d['showtime'] = template['showtime-date-stars'].getText(d);
            } else {
                d['showtime'] = template['showtime-date-time'].getText(d);
            }
            d['icon-video'] = _mediaCache.hasNonliveVideo(eventId) ? template['icon-video-nonlive'].getText(d) : '';
            d['event-result-id'] = eventResultId;
            d['icon-statistics'] = '';
            if (event[8]) {
                d['icon-statistics'] = template['icon-statistics'].getText(d);
            }
            d['draw'] = template['draw'].getText();
            var moreContent = '';
            d['more-opened'] = '';
            d['more-icon-hover'] = '';
            if ($M('more').isMoreOpened(eventResultId, 1)) {
                moreContent = $M('more').getContent(16);
            } else if ($M('more').isClosing(eventResultId, 1)) {
                moreContent = $M('more').getClosingContent();
            }
            if (moreContent) {
                d['more-opened'] = 'more-opened';
                d['more-icon-hover'] = 'more-icon-hover';
            }
            d['odds-count'] = cache.getEventMoreOddsCount(eventResultId);
            d['icon-more'] = d['odds-count'] ? template['icon-more'].getText(d) : '';
            d['sub-row'] = '';
            favourite = 'icon-nonlive-event-remove';
            d['icon-favourite-event'] = favTemplate[favourite].getText(d);
            for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
                var odds;
                var hdp = 0;
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    hdp = odds[1][4];
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds && !hdp) {
                    hdp = odds[1][4];
                }
                d['hdp-type'] = hdp ? (hdp > 0 ? 1 : 2) : 0;
                d['home-color-class'] = hdp > 0 ? 'Red' : 'Blue';
                d['away-color-class'] = hdp < 0 ? 'Red' : 'Blue';
                odds = oddsFTimeHDP ? oddsFTimeHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeHDP);
                }
                odds = oddsFHalfHDP ? oddsFHalfHDP[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfHDP);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfHDP);
                }
                odds = oddsFTimeOU ? oddsFTimeOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FTimeOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FTimeOU);
                }
                odds = oddsFHalfOU ? oddsFHalfOU[rowIndex] : null;
                if (odds) {
                    OddsUtility.populateOdds(d, odds, template['price-text'], cache.getPriceAdjustIndicators(odds[0]), null, null, selectedOddId);
                    OddsUtility.populateOddsPoints(d, odds);
                    OddsUtility.populateOddsLabels(d, odds);
                    OddsUtility.populateOddsIndicators(d, odds, cache.getPriceAdjustIndicators(odds[0]), 'price-up', 'price-down');
                } else {
                    OddsUtility.clearOdds(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsPoints(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsLabels(d, _MarketDisplay.FHalfOU);
                    OddsUtility.clearOddsIndicators(d, _MarketDisplay.FHalfOU);
                }
                d['row-index'] = oddsRowIndex;
                oddsRowIndex++;
                rows.push(template[(templateRowIndex & 1) ? 'row-event-alt' : 'row-event'].getText(d));
                d['icon-video'] = null;
                d['icon-statistics'] = null;
                d['showtime'] = null;
                d['live-time'] = null;
                d['home'] = null;
                d['away'] = null;
                d['draw'] = null;
                d['icon-more'] = null;
                d['sub-row'] = 'subrow';
                d['icon-favourite-event'] = null;
            }
            rows.push(moreContent);
            templateRowIndex++;
            if (templateRowIndex >= limitedRow) {
                if (!$M('global').hasVerticalScroll()) {
                    if (templateRowIndex >= (limitedRow * 2)) {
                        $M('odds-display').setDisplaySetting('limited-rows', limitedRow * 2);
                        rows.push(template['row-loading'].getText(d));
                        break;
                    }
                } else {
                    rows.push(template['row-loading'].getText(d));
                    break;
                }
            }
        }
        if (templateRowIndex == c && c > 0) {
            $M('odds-display').setDisplaySetting('limited-rows', Number.MAX_VALUE);
        }
        d['refresh-count'] = _syn.nonliveRefreshCount;
        d['refresh-button'] = _syn.nonliveCooldownCount ? template['refresh-refreshing'].getText() : template['refresh-countdown'].getText(d);
        if (rows.length > 0) {
            d['rows'] = rows.join('');
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        } else if (cache.isEmpty() && _syn.nonliveVersion == 0) {
            _drawLoading();
        } else {
            d['rows'] = template['row-nodata'].getText(d);
            d['table'] = template['table'].getText(d);
            d['odds-display-nonlive'] = template['odds-display-nonlive'].getText(d);
        }
    }

    function _getAdditionalClass() {
        var sportId = $M('odds-display').getDisplaySetting('sport');
        switch (parseInt(sportId)) {
        case 2:
            return _templateLive['basketball-additional-class'].getText();
        default:
            return '';
        }
    }

    function _drawRefreshButtons(section) {
        if (!_templateLive) {
            _syn.waitingTemplate = true;
            return;
        }
        if (!_templateNonlive) {
            _syn.nonliveWaitingTemplate = true;
            return;
        }
        if (section === undefined || section == 'live') {
            var a = document.getElementById('bu:od:refresh-live:button');
            if (a) {
                if (_syn.liveCooldownCount) {
                    a.innerHTML = _templateLive['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _templateLive['refresh'].getText();
                } else {
                    a.innerHTML = _templateLive['refresh-countdown'].getText({
                        'refresh-count': _syn.liveRefreshCount
                    });
                }
            }
        }
        if (section === undefined || section == 'nonlive') {
            a = document.getElementById('bu:od:refresh-nonlive:button');
            if (a) {
                if (_syn.nonliveCooldownCount) {
                    a.innerHTML = _templateNonlive['refresh-refreshing'].getText();
                } else if (a.isHover) {
                    a.innerHTML = _templateNonlive['refresh'].getText();
                } else {
                    a.innerHTML = _templateNonlive['refresh-countdown'].getText({
                        'refresh-count': _syn.nonliveRefreshCount
                    });
                }
            }
        }
    }
}

function __Cache_Ticket() {
    var _ticketDataIdx = {
        sportType: 0,
        tournamentName: 1,
        homeTeam: 2,
        awayTeam: 3,
        marketName: 4,
        marketType: 5,
        HDP: 6,
        betTeam: 7,
        betOption: 8,
        oddsValue: 9,
        newOddsValue: 10,
        isOddsConStake: 11,
        minBet: 12,
        maxBet: 13,
        isLive: 14,
        hdpType: 15,
        defaultStake: 16,
        autoRfOddsOpt: 17,
        autoAcctOddsOpt: 18,
        lastBetCount: 19,
        betPage: 20,
        betTypeGrName: 21,
        betCondition: 22,
        homeLiveScore: 23,
        awayLiveScore: 24,
        oddsId: 25,
        oddsStyle: 26,
        optionType: 27,
        eventResultId: 28,
        isAlert: 29,
        isMPOffered: 30,
        isOR: 31,
        isDoublePrmo: 32
    };
    var _tkDataLength = 33;
    var _singleOrder = [];
    var _mpTicketData = [];
    var _mpDataIdx = {
        oddsValue: 0,
        minBet: 1,
        maxBet: 2,
        orders: 3,
        defaultStake: 4,
        lBetCount: 5,
        doublePromo: 6
    };
    var _mpOrderIdx = {
        marketName: 0,
        homeTeam: 1,
        awayTeam: 2,
        betOption: 3,
        oddsValue: 4,
        eventId: 5,
        hdpType: 6,
        sportsName: 7,
        groupName: 8,
        sportsFName: 9,
        oddsId: 10,
        option: 11,
        marketType: 12
    };
    var _siParam = {
        id: -1,
        odds: 0,
        op: '',
        isor: -1,
        isLive: -1,
        style: '',
        hdpType: '',
        hidRefreshOdds: '',
        hidAuto: '',
        betPage: 0
    };
    var _oldOddsValue = -999;
    var _oldHDPScoreInfo = [];
    this.update = function (data) {
        if (data != undefined && data) {
            if (!_singleOrder || _singleOrder.length == 0) {
                _singleOrder = data;
            } else {
                _oldOddsValue = _singleOrder[_ticketDataIdx.oddsValue];
                _oldHDPScoreInfo = _singleOrder[_ticketDataIdx.HDP];
                for (var i = 0; i < _tkDataLength; i++) {
                    if (data[i]) {
                        if (data[i] != _singleOrder[i]) {
                            data[i] = (parseFloat(data[i]) == -1) && i != _ticketDataIdx.oddsValue ? 0 : data[i];
                            _singleOrder[i] = data[i];
                        }
                    } else if (i == 32) {
                        _singleOrder[i] = data[i];
                    }
                }
            }
            _singleOrder[_ticketDataIdx.isOddsConStake] = _singleOrder[_ticketDataIdx.isOddsConStake] == -1 ? 0 : 1;
            _updateSiParam();
        }
    };
    this.mpUpdate = function (data) {
        if (data != undefined && data) {
            if (data.b.length < 1) {
                _mpTicketData = [];
                return false;
            }
            var overallInfo = data.o;
            _mpTicketData[_mpDataIdx.oddsValue] = overallInfo[0];
            _mpTicketData[_mpDataIdx.minBet] = overallInfo[1];
            _mpTicketData[_mpDataIdx.maxBet] = overallInfo[2];
            _mpTicketData[_mpDataIdx.orders] = data.b;
            _mpTicketData[_mpDataIdx.defaultStake] = data.ds;
            _mpTicketData[_mpDataIdx.lBetCount] = data.lbc;
            _mpTicketData[_mpDataIdx.doublePromo] = data.doublePromo;
        }
        _refreshSiParm();
        return true;
    };
    this.getMPOddsValue = function () {
        return _mpTicketData[_mpDataIdx.oddsValue];
    }
    this.getSimpleOddsValue = function () {
        return _singleOrder[_ticketDataIdx.oddsValue];
    }
    this.getSimpleOddsOption = function () {
        return _singleOrder[_ticketDataIdx.optionType];
    }
    this.getSimpleOddsId = function () {
        return _singleOrder[_ticketDataIdx.oddsId];
    }
    this.getParlayOddsId = function () {
        var oids = [];
        var orders = _mpTicketData[_mpDataIdx.orders];
        if (orders) {
            for (var i = 0; i < orders.length; i++) {
                if (i > 0) {
                    oids.push('~');
                }
                oids.push(orders[i][_mpOrderIdx.oddsId]);
            }
        }
        return oids.join('');
    }
    this.onUpdateBetterOddsBox = function (flag) {
        if (parseInt(flag, 10) == 1) {
            _singleOrder[_ticketDataIdx.autoAcctOddsOpt] = "True";
        } else {
            _singleOrder[_ticketDataIdx.autoAcctOddsOpt] = "False";
        }
    }
    this.onUpdateAutoRefreshBox = function (flag) {
        if (parseInt(flag, 10) == 1) {
            _singleOrder[_ticketDataIdx.autoRfOddsOpt] = "True";
        } else {
            _singleOrder[_ticketDataIdx.autoRfOddsOpt] = "False";
        }
    }
    this.isBetterOdds = function () {
        if (_oldOddsValue == -999) {
            return false;
        };
        var currOdds = parseFloat(_oldOddsValue);
        var nextOdds = parseFloat(_singleOrder[_ticketDataIdx.oddsValue]);
        if ((currOdds < 0 && nextOdds < 0 && nextOdds > currOdds) || (currOdds > 0 && (nextOdds < 0 || nextOdds > currOdds))) {
            return true;
        } else {
            return false;
        }
    }
    this.isOddsChanged = function () {
        if (_oldOddsValue == -999) {
            return false;
        };
        if (parseFloat(_oldOddsValue) != parseFloat(_singleOrder[_ticketDataIdx.oddsValue])) {
            return true;
        }
    }
    this.isScoreChanged = function () {
        if (_oldHDPScoreInfo.length < 1 || (_singleOrder[_ticketDataIdx.HDP] && _singleOrder[_ticketDataIdx.HDP].length < 1)) {
            return false;
        };
        if ((parseFloat(_oldHDPScoreInfo[1]) != parseFloat(_singleOrder[_ticketDataIdx.HDP][1])) || (parseFloat(_oldHDPScoreInfo[2]) != parseFloat(_singleOrder[_ticketDataIdx.HDP][2]))) {
            return true;
        }
    }
    this.resetOldOddsValue = function () {
        _oldOddsValue = -999;
    }
    this.resetOldHDPScoreInfo = function () {
        _oldHDPScoreInfo = [];
    }
    this.updateORRefreshedOdds = function (data) {
        if (data) {
            _oldOddsValue = _singleOrder[_ticketDataIdx.oddsValue];
            _singleOrder[_ticketDataIdx.oddsValue] = data[_ticketDataIdx.oddsValue];
            _singleOrder[_ticketDataIdx.isDoublePrmo] = data[_ticketDataIdx.isDoublePrmo];
        }
    };
    this.updateSimpleTicketStake = function (value) {
        _singleOrder[_ticketDataIdx.defaultStake] = value;
    }
    this.getSimpleTicketStake = function () {
        return _singleOrder[_ticketDataIdx.defaultStake];
    }
    this.updateParlayTicketStake = function (value) {
        _mpTicketData[_mpDataIdx.defaultStake] = value;
    }
    this.getParlayTicketStake = function () {
        return _mpTicketData[_mpDataIdx.defaultStake];
    }
    this.makeSiParam = function () {
        sb = [];
        sb.push('&id=' + _siParam.id);
        sb.push('&odds=' + _siParam.odds);
        sb.push('&op=' + _siParam.op);
        sb.push('&isor=' + _siParam.isor);
        sb.push('&isLive=' + _siParam.isLive);
        sb.push('&style=' + _siParam.style);
        sb.push('&hdpType=' + _siParam.hdpType);
        sb.push('&hidRefreshOdds=' + _siParam.hidRefreshOdds);
        sb.push('&hidAuto=' + _siParam.hidAuto);
        sb.push('&betpage=' + _siParam.betPage);
        return sb.join('');
    }
    this.clearSingleOrder = function () {
        _singleOrder = [];
    };
    this.clearParlayOrder = function () {
        _mpTicketData = [];
    };
    this.getSingleOrderData = function () {
        return _singleOrder;
    };
    this.isAnySingleOrder = function () {
        return _singleOrder.length > 0 ? 1 : 0;
    };
    this.isLiveTicket = function () {
        return _singleOrder[_ticketDataIdx.isLive] == 1;
    }
    this.getDefaultStake = function (type) {
        if (type && type == 1) {
            if (_singleOrder[_ticketDataIdx.defaultStake]) {
                return parseFloat(_singleOrder[_ticketDataIdx.defaultStake]);
            }
        } else {
            if (_mpTicketData[_mpDataIdx.defaultStake]) {
                return parseFloat(_mpTicketData[_mpDataIdx.defaultStake]);
            }
        }
        return -1;
    };
    this.isOROrder = function () {
        return _singleOrder[_ticketDataIdx.isOR] > 0 ? true : false;
    };
    this.isCurrentOddsIsMP = function () {
        return _singleOrder[_ticketDataIdx.isMPOffered] == 1;
    };
    this.getCurrentPage = function () {
        return _singleOrder[_ticketDataIdx.betPage];
    }
    this.getCurrentMarketType = function () {
        return _singleOrder[_ticketDataIdx.marketType];
    }
    this.getCurrentOrderOddsStyle = function () {
        return _singleOrder[_ticketDataIdx.oddsStyle];
    }
    this.getLastBetCount = function () {
        return _singleOrder[_ticketDataIdx.lastBetCount];
    };
    this.updateLastBetCount = function (num) {
        _singleOrder[_ticketDataIdx.lastBetCount] = parseInt(num, 10);
    };
    this.updateMPLastBetCount = function (num) {
        _mpTicketData[_mpDataIdx.lBetCount] = num;
    }
    this.isBetPageLS = function () {
        return _singleOrder[_ticketDataIdx.betPage] == $M('ticket').getBetPageEnum('liveSport');
    }
    this.getMPLastBetCount = function () {
        return _mpTicketData[_mpDataIdx.lBetCount];
    };
    this.getTotalMPBetCount = function () {
        if (_mpTicketData) {
            if (_mpTicketData[_mpDataIdx.orders]) {
                return _mpTicketData[_mpDataIdx.orders].length;
            }
        }
        return 0;
    };
    this.getMPOrderData = function () {
        return _mpTicketData;
    }

    function _updateSiParam() {
        _siParam.id = _singleOrder[_ticketDataIdx.oddsId];
        _siParam.op = _singleOrder[_ticketDataIdx.optionType];
        _siParam.isLive = _singleOrder[_ticketDataIdx.isLive];
        _siParam.style = _singleOrder[_ticketDataIdx.oddsStyle];
        _siParam.hdpType = _singleOrder[_ticketDataIdx.hdpType];
        _siParam.betPage = _singleOrder[_ticketDataIdx.betPage];
    }

    function _refreshSiParm() {
        _siParam.id = -1;
        _siParam.odds = 0;
        _siParam.op = '';
        _siParam.isor = -1;
        _siParam.isLive = -1;
        _siParam.style = '';
        _siParam.hdpType = '';
        _siParam.hidRefreshOdds = '';
        _siParam.hidAuto = '';
        _siParam.betPage = 0;
    }
    this.updateHidRefreshOddParm = function (val) {
        _siParam.hidRefreshOdds = val;
    }
    this.updateHidAutoParm = function (val) {
        _siParam.hidAuto = val;
    }
    this.updateIsORParm = function (val) {
        _siParam.isor = val;
    }
    this.updateDecryptedOddsVal = function (val) {
        _siParam.odds = val;
    }
}

function __Module_Ticket(loginName, currency, exchangeRate) {
    var _TemplateName = 'ticket/ticket';
    var _template = null;
    var _self = this;
    var _ticketCache = new __Cache_Ticket();
    var _minTotalMPOrderWithoutScrollDiv = 3;
    var _loginName = loginName;
    var _currency = currency;
    var _exRate = exchangeRate;
    var _temp = 0;
    var _MixParlayMinCount = 3;
    var _syn = {
        oddsEncVersion: 0,
        ticket: 1,
        totalSimpleOrder: 0,
        isOddsConStake: -1,
        ticketOdds: -1,
        isSameSport: 1,
        isRefreshChecked: false,
        oddsRefreshRate: -1,
        oddsRefreshCount: 0,
        isAutoAcceptBetterOdds: false,
        isAutoAccept: false,
        isAutoCheckedBeforeDraw: false,
        isAnyOddsAccept: false,
        minBet: -1,
        maxBet: -1,
        isOrdProcessing: false,
        isFromTicket: false,
        isJustSubmitted: false,
        isFirstTimeDraw: false,
        invalidOddsErr: 0,
        isTicketOpened: false,
        isTicketClicked: false,
        isSameTicket: false
    };
    var _ticketDataIdx = {
        sportType: 0,
        tournamentName: 1,
        homeTeam: 2,
        awayTeam: 3,
        marketName: 4,
        marketType: 5,
        HDP: 6,
        betTeam: 7,
        betOption: 8,
        oddsValue: 9,
        newOddsValue: 10,
        isOddsConStake: 11,
        minBet: 12,
        maxBet: 13,
        isLive: 14,
        hdpType: 15,
        defaultStake: 16,
        autoRfOddsOpt: 17,
        autoAcctOddsOpt: 18,
        lastBetCount: 19,
        betPage: 20,
        betTypeGrName: 21,
        betCondition: 22,
        homeLiveScore: 23,
        awayLiveScore: 24,
        oddsId: 25,
        oddsStyle: 26,
        optionType: 27,
        eventResultId: 28,
        isAlert: 29,
        isMPOffered: 30,
        isOR: 31,
        isDoublePromo: 32
    };
    var _mpDataIdx = {
        oddsValue: 0,
        minBet: 1,
        maxBet: 2,
        orders: 3,
        defaultStake: 4,
        lBetCount: 5,
        isDoublePromo: 6
    };
    var _mpOrderIdx = {
        marketName: 0,
        homeTeam: 1,
        awayTeam: 2,
        betOption: 3,
        oddsValue: 4,
        eventId: 5,
        hdpType: 6,
        sportsName: 7,
        groupName: 8,
        sportsFName: 9,
        oddsId: 10,
        oddOption: 11,
        marketType: 12
    };
    var _rfTimeOutID = 0;
    var _refreshLbl = 1;
    var _siReceipt = {
        refNO: '',
        isHdpPoint: '',
        hdpPoint: '',
        score: '',
        price: '',
        oddsChoice: '',
        currency: '',
        stake: '',
        status: '',
        winAmount: '',
        tmplType: '',
        totalGoal: '',
        betType: ''
    };
    var BetPageEnum = {
        unknown: 0,
        liveSport: 1,
        oddsDisplay: 2,
        interestedEvent: 3,
        singlePage: 4,
        doublePage: 5,
        more: 6,
        favourite: 7
    };
    var _marketTypeInBlueForOption = ':5:8:11:15:16:17:';
    this.initiate = function () {
        TiLib.Timer.addToSecondTimer(_self);
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        $M('ticket').getTicket();
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_syn.waitingTemplate) {
                    if (_template) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                }
            }
        }
    };
    this.getTicket = function () {
        var betpage = 0;
        if ($M('live-sport-display')) {
            betpage = 1;
            _submit('&refreshed=1&betpage=' + betpage);
        } else {
            betpage = 2;
            _submitMP('&refreshed=1');
            _submit('&refreshed=1&betpage=' + betpage);
        }
    }
    this.getBetPageEnum = function (id) {
        var page = BetPageEnum[id];
        if (!page) {
            page = 0;
        }
        return page;
    }
    var _disabledGetOddsIdOption = false;
    this.getOddsIdDictionary = function (force) {
        if (_disabledGetOddsIdOption && !force) return null;
        var mpData = _ticketCache.getMPOrderData();
        var ret = {};
        if (mpData) {
            var oids = [];
            var orders = mpData[3];
            var order = null;
            var key = 0;
            if (orders) {
                for (var i = 0; i < orders.length; i++) {
                    order = orders[i];
                    var options = [];
                    if (order) {
                        key = order[10] + order[11];
                        options.push('bu:od:mpprice');
                        options.push(order[10]);
                        options.push(order[11]);
                        if (order[12] == 4 || order[12] == 14) {
                            options.push(order[4]);
                        } else {
                            options.push(TiLib.Number.toString(order[4], 3, 2));
                        }
                        options.push(order[6]);
                        ret[key] = options;
                    }
                }
            }
        }
        return ret;
    }
    this.getOddIdOption = function (force) {
        if (_disabledGetOddsIdOption && !force) return null;
        var oddId = _ticketCache.getSimpleOddsId();
        var ret = null;
        if (oddId) {
            var oddOption = _ticketCache.getSimpleOddsOption();
            if (oddOption) {
                ret = oddId + oddOption;
            }
        }
        return ret;
    }
    this.getOddIdOptions = function (force) {
        if (_disabledGetOddsIdOption && !force) return null;
        var oddId = _ticketCache.getSimpleOddsId();
        var oddOption = _ticketCache.getSimpleOddsOption();
        var data = _ticketCache.getSingleOrderData();
        var price = _getDOddsPrice(data[_ticketDataIdx.oddsValue]);
        var marketType = data[_ticketDataIdx.marketType];
        var oddsPrice = (marketType == 4 || marketType == 14) ? price : TiLib.Number.toString(price, 3, 2);
        var hdpType = data[_ticketDataIdx.hdpType];
        var ret = [];
        ret.push('bu:od:price');
        ret.push(oddId);
        ret.push(oddOption);
        ret.push(oddsPrice);
        ret.push(hdpType);
        return ret;
    }
    this.setDisabledGetOddsIdOption = function (value) {
        _disabledGetOddsIdOption = value;
    }
    this.drawWithoutSelectedOdds = function () {
        _disabledGetOddsIdOption = true;
        if ($M('odds-display') && $M('odds-display').draw) {
            $M('odds-display').draw();
        }
        if ($M('interested-event') && $M('interested-event').draw) {
            $M('interested-event').draw();
        }
        if ($M('live-sport-display') && $M('live-sport-display').draw) {
            $M('live-sport-display').draw();
        }
    }
    this.isLiveTicket = function () {
        return _ticketCache.isLiveTicket();
    }
    this.openTicket = function (id, option, price, hdpType, isor, isLive, betpage, oddsSource) {
        var sb = [];
        sb.push('&id=' + id);
        sb.push('&op=' + option);
        sb.push('&odds=' + price);
        sb.push('&hdpType=' + hdpType);
        var oR = isor ? 1 : 0;
        var iLive = isLive ? 1 : 0;
        sb.push('&isor=' + oR);
        sb.push('&isLive=' + iLive);
        if ($M('live-sport-display')) {
            betpage = _self.getBetPageEnum('liveSport');
        }
        if (oddsSource && betpage == _self.getBetPageEnum('oddsDisplay')) {
            betpage = oddsSource;
        }
        sb.push('&betpage=' + betpage);
        sb.push('&style=' + _getDisplaySetting('price-style'));
        _syn.isJustSubmitted = false;
        _submit(sb.join(''));
        _oldOddId = 0;
        _oldOddOption = 0;
    };
    this.openMPTicket = function (id, option, price, hdpType) {
        var sb = [];
        sb.push('&id=' + id);
        sb.push('&odds=' + price);
        sb.push('&op=' + option);
        sb.push('&hdpType=' + hdpType);
        sb.push('&style=' + _getDisplaySetting('price-style'));
        sb.push('&mp_action=add');
        _submitMP(sb.join(''), 'mp');
        _oldOddId = 0;
        _oldOddOption = 0;
    };
    this.hideTicket = function () {
        var tDiv = _getDiv('tk:tk');
        if (tDiv) {
            tDiv.className = 'ticket-content hide';
        }
        var mDiv = _getDiv('tk:mp');
        if (mDiv) {
            mDiv.className = 'mp-content hide';
        }
        if ($M('global') && $M('global').scrollDivMyBet) {
            $M('global').scrollDivMyBet(true);
        }
        _syn.isTicketOpened = false;
    }
    this.show = function () {
        if ($M('global') && $M('global').isSmallScreen) {
            if ($M('global').isSmallScreen()) {
                _draw();
            }
        }
    }
    this.hide = function () {
        if ($M('global') && $M('global').isSmallScreen) {
            if ($M('global').isSmallScreen()) {
                if ((_syn.ticket == 1 && _ticketCache.isAnySingleOrder()) || (_syn.ticket == 0 && _ticketCache.getTotalMPBetCount() > 0)) {
                    _self.hideTicket();
                }
            }
        }
    }
    this.onUpdate = function (data, encVersion, isRefresh, exchangeRate) {
        _syn.oddsEncVersion = parseInt(encVersion, 10);
        if (!isRefresh) {
            _ticketCache.clearSingleOrder();
            _syn.isFirstTimeDraw = true;
            _syn.isTicketClicked = false;
            _resetAcceptOddsCondition();
            _syn.isSameTicket = false;
        } else {
            _syn.isFirstTimeDraw = false;
        }
        _ticketCache.update(data);
        _clearSelectedOdds();
        if (exchangeRate) {
            _exRate = exchangeRate;
        }
        _syn.ticket = 1;
        _syn.isSameSport = 1;
        if (isRefresh && isRefresh == 1) {
            if (_syn.isAutoAccept && _ticketCache.isBetterOdds()) {
                _onSubmitTicket(false, 1);
                return;
            }
        } else {
            _onUpdateStake(_ticketCache.getDefaultStake(1));
        }
        if (_syn.isJustSubmitted == true && _ticketCache.isOddsChanged()) {
            _drawErrorResponse(11);
            _syn.isJustSubmitted = false;
            return;
        }
        this.draw();
        _syn.isFirstTimeDraw = false;
    };
    this.onOrderSubmitted = function () {
        _syn.isOrdProcessing = false;
        if ($M('interested-event')) {
            $M('interested-event').onOrderSubmitted();
        }
        setTimeout(_clearSelectedOdds, 500);
    }
    this.onResetTicket = function (type) {
        _syn.isOrdProcessing = false;
        _resetTicketCache(type);
        _draw();
        $M('ticket').hideTicket();
        setTimeout(_clearSelectedOdds, 500);
    }
    this.onUpdateBetterOddsBox = function (value) {
        if (_syn.ticket == 1) {
            _ticketCache.onUpdateBetterOddsBox(value);
        }
    }
    this.onUpdateAutoRefreshBox = function (value) {
        if (_syn.ticket == 1) {
            _ticketCache.onUpdateAutoRefreshBox(value);
            _draw();
        }
    }
    this.onMPUpdate = function (data, exchangeRate) {
        _syn.isTicketClicked = false;
        _syn.isAutoAccept = false;
        if (exchangeRate) {
            _exRate = exchangeRate;
        }
        var cleared = 0;
        if (!_ticketCache.mpUpdate(data)) {
            _clearSelectedOdds();
            cleared = 1;
            if (_syn.ticket == 1) {
                return;
            }
        }
        if (!cleared) {
            _clearSelectedOdds();
        }
        _syn.ticket = 0;
        _syn.isOddsConStake = 0;
        _syn.isSameSport = 1;
        if (_rfTimeOutID) {
            _clearTimeOutRF();
        };
        _onUpdateStake(_ticketCache.getDefaultStake());
        _syn.ticketOdds = parseFloat(_ticketCache.getMPOddsValue());
        this.draw();
    };
    this.onMPOddsEventClosed = function (error) {
        _syn.ticket = 0;
        this.onOddsEventClosed(error);
    }
    this.onOddsEventClosed = function (error) {
        _syn.isOrdProcessing = false;
        if (!error) {
            error = 999;
        }
        _syn.invalidOddsErr = error;
        _resetTicketCache(_syn.ticket);
        _draw();
        _clearSelectedOdds();
    };
    this.onAlert = function (message, type) {
        if (type && type == 'ochanged' && _syn.isFromTicket) {
            return;
        }
        if (type && (type == 'hdpchanged' || type == 'scorechanged') && _syn.ticket == 1) {
            var apb = _getDiv("tk:tk:autoprocess");
            if (apb && apb.checked) {
                apb.checked = false;
                $M('ticket').onAutoProcessBet();
            };
        }
        alert(message);
    }
    this.onORRefreshedData = function (data, encVersion) {
        _syn.oddsEncVersion = parseInt(encVersion, 10);
        _ticketCache.updateORRefreshedOdds(data);
        if (_syn.isAutoAccept && _ticketCache.isBetterOdds()) {
            _onSubmitTicket(false, 1);
            return;
        };
        this.draw();
    };
    this.showOrderResult = function (res, lastBetCount) {
        _syn.isOrdProcessing = false;
        if (lastBetCount) {
            _ticketCache.updateLastBetCount(lastBetCount);
        }
        if (res == 101) {
            $M('page-head').onUpdateBetCredit();
            alert(_template['msg-tk-success'].getText());
            $M('mini-bet-list').openBetlistMini();
            _resetAcceptOddsCondition();
        } else if (res == 102) {
            $M('page-head').onUpdateBetCredit();
            $M('mini-bet-list').openBetlistMini();
            _resetAcceptOddsCondition();
        } else {
            if (res >= 2 && res <= 10) {
                _drawErrorResponse(res);
            } else {
                _drawErrorResponse(3);
            }
            setTimeout('$M(\'mini-bet-list\').openBetlistMini()', 5000);
        }
    };
    this.onUpdateBetReceipt = function (pendingRef, receiptData) {
        if (pendingRef && receiptData) {
            _siReceipt.refNO = pendingRef;
            _siReceipt.isHdpPoint = receiptData[0];
            _siReceipt.hdpPoint = receiptData[1];
            _siReceipt.score = receiptData[2];
            _siReceipt.price = receiptData[3];
            _siReceipt.oddsChoice = receiptData[4];
            _siReceipt.currency = receiptData[5];
            _siReceipt.stake = receiptData[6];
            _siReceipt.status = receiptData[7];
            _siReceipt.winAmount = receiptData[8];
            _siReceipt.tmplType = receiptData[9];
            _siReceipt.totalGoal = receiptData[10];
            _siReceipt.betType = receiptData[11];
            _draw(true);
            setTimeout(function () {
                _resetAcceptOddsCondition();
                alert(_template['msg-tk-live-msg1'].getText());
                $M('mini-bet-list').openBetlistMini();
                _ticketCache.clearSingleOrder();
                _siReceipt.refNO = '';
                _siReceipt.isHdpPoint = '';
                _siReceipt.hdpPoint = '';
                _siReceipt.score = '';
                _siReceipt.price = '';
                _siReceipt.oddsChoice = '';
                _siReceipt.currency = '';
                _siReceipt.stake = '';
                _siReceipt.status = '';
                _siReceipt.winAmount = '';
                _siReceipt.tmplType = '';
                _siReceipt.totalGoal = '';
                _siReceipt.betType = '';
                $M('ticket').draw();
            }, 3);
        } else {
            $M('mini-bet-list').openBetlistMini();
            setTimeout(function () {
                alert(_template['msg-tk-live-msg2'].getText());
            }, 1);
        }
    };
    this.onIdle = function () {
        var ediv = _getDiv("tk:tk:error");
        if (ediv) {
            ediv.innerHTML = '';
            ediv.style.display = "none";
        };
        var pdiv = _getDiv("tk:tk:oddssection");
        if (pdiv) {
            var d = {};
            var data = _ticketCache.getSingleOrderData();
            var price = data[_ticketDataIdx.oddsValue];
            d['cls-price-red'] = price > 0 ? '' : 'Red';
            var oddsPrice = _getDOddsPrice(price);
            d['orderPrice'] = TiLib.Number.toString(oddsPrice, 3, 2);
            d['cls-odds-change'] = '';
            d['cls-price-down'] = '';
            pdiv.innerHTML = _template['simple-ticket-odd-section'].getText(d);
        }
        var sdiv = _getDiv("tk:tk:scoreinfo");
        if (sdiv) {
            sdiv.className = 'score ';
        }
    };

    function _submit(param) {
        var sb = [];
        sb.push('/web-root/restricted/ticket/ticket.aspx?');
        sb.push('loginname=' + _loginName);
        if (param) {
            sb.push(param);
        } else {
            sb.push(_ticketCache.makeSiParam());
        }
        return TiLib.Ajax.sendRequest('ticket', sb.join(''));
    }

    function _submitOrder(betcount, stake, ostyle, stakeInAuto, betpage, acceptIfAny) {
        var sb = [];
        sb.push('/web-root/restricted/ticket/confirm.aspx?');
        sb.push('loginname=' + _loginName);
        var sameTicket = _syn.isSameTicket ? 1 : 0;
        sb.push('&sameticket=' + sameTicket);
        sb.push(makeSiOrderParam(betcount, stake, ostyle, stakeInAuto, betpage, acceptIfAny));
        _syn.isSameTicket = true;
        return TiLib.Ajax.sendRequest('ticketO', sb.join(''));
    };

    function _submitMP(param) {
        var sb = [];
        sb.push('/web-root/restricted/ticket/ticketmp.aspx?');
        sb.push('loginname=' + _loginName);
        if (param) {
            sb.push(param);
        }
        return TiLib.Ajax.sendRequest('ticketMP', sb.join(''));
    }

    function _submitMPOrder(betcount, stake) {
        var sb = [];
        sb.push('/web-root/restricted/ticket/confirmmp.aspx?');
        sb.push('loginname=' + _loginName);
        sb.push('&betcount=' + betcount);
        sb.push('&stake=' + stake);
        var oid = _ticketCache.getParlayOddsId();
        sb.push('&oid=' + oid);
        return TiLib.Ajax.sendRequest('ticketMPO', sb.join(''));
    };

    function makeSiOrderParam(betcount, stake, ostyle, stakeInAuto, betpage, acceptIfAny) {
        sb = [];
        sb.push('&betcount=' + betcount);
        sb.push('&stake=' + stake);
        sb.push('&ostyle=' + ostyle);
        sb.push('&stakeInAuto=' + stakeInAuto);
        sb.push('&betpage=' + betpage);
        sb.push('&acceptIfAny=' + acceptIfAny);
        var oid = _ticketCache.getSimpleOddsId();
        sb.push('&oid=' + oid);
        return sb.join('');
    }

    function _resetTicketCache(type) {
        if (type == 1) {
            _ticketCache.clearSingleOrder();
            _resetAcceptOddsCondition();
        } else {
            _ticketCache.clearParlayOrder();
        };
    }
    this.onTime = function () {
        _getLatestMPCount();
    };
    this.onClick = function (event) {
        if (!_onTicketClick(event)) {
            event.returnValue = false;
            return false;
        };
    }

    function _onTicketClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'tk:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 1) {
                if (atom[0] == 'tk') {
                    if (atom[1] == 'tk') {
                        _syn.isTicketClicked = true;
                        switch (atom[2]) {
                        case 'autorefreshDiv':
                            _onAutoRefresh();
                            return true;
                        case 'addtomp':
                            _onAddToMixParlay();
                            return false;
                        case 'acceptbetterodds':
                            _onAcceptBetterOdds(0);
                            return true;
                        case 'acceptbetteroddsL':
                            _preventDefault(event);
                            _onAcceptBetterOdds(1);
                            return true;
                        case 'acceptanyodds':
                            _onAcceptAnyOdds(0);
                            return true;
                        case 'acceptanyoddsL':
                            _preventDefault(event);
                            _onAcceptAnyOdds(1);
                            return true;
                        case 'autoprocess':
                            return $M('ticket').onAutoProcessBet();
                        case 'canceltc':
                            _onCancelTicket();
                            return false;
                        case 'submittc':
                            _onSubmitTicket(false, 0);
                            return false;
                        }
                    }
                    if (atom[1] == 'mp') {
                        switch (atom[2]) {
                        case 'remove':
                            _onMPRemoveOrder(atom[3]);
                            return false;
                        case 'canceltc':
                            _onMPCancelTicket();
                            return false;
                        case 'submittc':
                            _onSubmitTicket(true, 0);
                            return false;
                        case 'gotomp':
                            _onOpenMixParlayOddsPage();
                            return false;
                        }
                    }
                    if (atom[1] == 'tab') {
                        switch (atom[2]) {
                        case 'ticket':
                            _onTicketTab();
                            return false;
                        case 'parlay':
                            _onParlayTab();
                            return false;
                        }
                    }
                } else if (atom[0] == 'stake') {
                    _syn.isTicketClicked = true;
                    _onStake(1);
                }
            }
        }
    }

    function _setResetStakeWord(isreset, ishighlighted) {
        var stakeL = _getDiv('stake:label');
        if (stakeL) {
            if (isreset) {
                stakeL.innerHTML = '';
            } else {
                stakeL.innerHTML = _template['msg-tk-stake'].getText();
                if (ishighlighted) {
                    stakeL.className = 'FormTextN';
                } else {
                    stakeL.className = 'FormTextF';
                }
            }
        }
    }
    this.onMouseOutFromStake = function () {
        var stake = _getDiv('stake');
        if (stake) {
            if (isNaN(_removeCommas(stake.value)) || stake.value == '') {
                _setResetStakeWord(0, 1);
                stake.className = 'stake-input stake-text-dark';
            }
        }
    };
    this.onRefresh = function () {
        if (!_syn.isRefreshChecked) {
            return;
        }
        if (_syn.oddsRefreshCount == 0) {
            var rfLbl = _getDiv('tk:tk:autorefreshLbl');
            if (rfLbl) {
                rfLbl.innerHTML = _syn.oddsRefreshCount;
                rfLbl.className = '';
            }
            _ticketCache.updateHidRefreshOddParm('refresh');
            _submit();
            _syn.oddsRefreshCount = _syn.oddsRefreshRate;
            _clearTimeOutRF();
        } else {
            var rfLbl = _getDiv('tk:tk:autorefreshLbl');
            if (rfLbl) {
                rfLbl.innerHTML = _syn.oddsRefreshCount;
                rfLbl.className = '';
            }
            _syn.oddsRefreshCount -= 1;
        }
        if (_syn.isRefreshChecked) {
            _rfTimeOutID = setTimeout('$M(\'ticket\').onRefresh()', 1000);
        }
    }

    function _onStake(isLight) {
        var stake = _getDiv('stake');
        if (stake) {
            if (isNaN(_removeCommas(stake.value)) || stake.value == '') {
                if (isLight && isLight == 1) {
                    _setResetStakeWord(0, 0);
                    stake.focus();
                } else {
                    _setResetStakeWord(0, 1);
                }
                return false;
            }
        }
        return true;
    }
    this.onKeyUpStake = function (stake) {
        var val = _removeCommas(stake.value);
        if (_syn.ticket == 1) {
            _onAutoProcessBet();
        }
        if (isNaN(val) || stake.value == '') {
            _onUpdateStake(0);
            _calEstPO('0');
            _setResetStakeWord(0, 0);
            return;
        } else {
            _setResetStakeWord(1);
        }
        _calculatePO(stake);
    };
    this.onStakeFormat = function (stake, event) {
        var stake = _getDiv("stake");
        if (stake) {
            if (isNaN(_removeCommas(stake.value)) || stake.value == '') {
                stake.value = '';
            }
            _setResetStakeWord(1);
        }
        var whichCode = (window.Event && event.which) ? event.which : event.keyCode;
        if (whichCode == 13) return false;
        if (whichCode == 9 || (whichCode == 46 && !String.fromCharCode(whichCode) == ".")) return true;
        if ((whichCode >= 48 && whichCode <= 57) || whichCode == 8) {
            var n = stake.value.replace(/,/g, "");
            if (whichCode == 8) {
                if (n.length != 0)
                    n = n.substr(0, n.length - 1);
            }
            if (parseInt(n, 10) == 0) n = '';
            return true;
        }
        return false;
    };

    function _preventDefault(event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    }

    function _onAutoRefresh() {
        var rf = _getDiv("tk:tk:autorefresh");
        if (!rf) {
            return;
        }
        var op = '';
        if (_syn.isRefreshChecked) {
            _syn.isRefreshChecked = false;
            _clearTimeOutRF();
            rf.checked = false;
            op = "0";
            rf.title = _template['msg-tk-enable-refresh'].getText();
            var rfL = _getDiv("tk:tk:autorefreshLbl");
            if (rfL) {
                rfL.className = 'ticket-refresh';
                rfL.innerHTML = '';
            }
        } else {
            _syn.isRefreshChecked = true;
            op = "1";
            rf.checked = true;
            _syn.oddsRefreshCount = _syn.oddsRefreshRate;
            rf.title = _template['msg-tk-disable-refresh'].getText();
            $M('ticket').onRefresh();
        }
        _ticketCache.updateHidRefreshOddParm('change');
        _ticketCache.updateHidAutoParm(op);
        _submit();
        _onAutoProcessBet();
    }

    function _onUpdateStake(value) {
        if (_syn.ticket == 1) {
            _ticketCache.updateSimpleTicketStake(value);
        } else {
            _ticketCache.updateParlayTicketStake(value);
        }
    }

    function _getTicketStake() {
        if (_syn.ticket == 1) {
            return _ticketCache.getSimpleTicketStake();
        } else {
            return _ticketCache.getParlayTicketStake();
        }
    }

    function _onAddToMixParlay() {
        var data = _ticketCache.getSingleOrderData();
        $M('ticket').openMPTicket(data[_ticketDataIdx.oddsId], data[_ticketDataIdx.optionType], _getDOddsPrice(data[_ticketDataIdx.oddsValue]), data[_ticketDataIdx.hdpType]);
        _syn.isFromTicket = true;
    };

    function _onAcceptBetterOdds(isToggle) {
        var abo = _getDiv("tk:tk:acceptbetterodds");
        abo.checked = isToggle ? !abo.checked : abo.checked;
        var ano = _getDiv("tk:tk:acceptanyodds");
        if (abo && ano) {
            var op;
            if (abo.checked) {
                op = "1";
                ano.checked = false;
                _syn.isAnyOddsAccept = false;
            } else {
                op = "0";
            }
            _ticketCache.updateHidRefreshOddParm('autoaccept');
            _ticketCache.updateHidAutoParm(op);
            _submit();
        }
        _onAutoProcessBet();
    };

    function _onAcceptAnyOdds(isToggle) {
        var ano = _getDiv("tk:tk:acceptanyodds");
        ano.checked = isToggle ? !ano.checked : ano.checked;
        var abo = _getDiv("tk:tk:acceptbetterodds");
        if (ano && abo) {
            if (ano.checked) {
                abo.checked = false;
                hidAuto = true;
                _syn.isAnyOddsAccept = true;
            } else {
                _syn.isAnyOddsAccept = false;
            }
            _ticketCache.updateHidRefreshOddParm('autoaccept');
            _ticketCache.updateHidAutoParm("0");
            _submit();
        }
        _onAutoProcessBet();
    };
    this.onAutoProcessBet = function () {
        _onStake();
        _onAutoProcessBet();
        return true;
    }

    function _onAutoProcessBet(flag) {
        _syn.isAutoAccept = false;
        var aboCheckStatus = false;
        if (flag && flag == 1) {
            aboCheckStatus = _syn.isAutoCheckedBeforeDraw;
        }
        var apb = _getDiv("tk:tk:autoprocess");
        var flag = 0;
        if (apb) {
            var abo = _getDiv("tk:tk:acceptbetterodds");
            if (_syn.isRefreshChecked && abo && abo.checked) {
                flag = 1;
                apb.tabIndex = 5;
                _getDiv("tk:tk:canceltc").tabIndex = 6;
                _getDiv("tk:tk:submittc").tabIndex = 7;
            } else {
                flag = 0;
                apb.checked = false;
                apb.tabIndex = '';
                _getDiv("tk:tk:canceltc").tabIndex = 5;
                _getDiv("tk:tk:submittc").tabIndex = 6;
            }
            var stake = _getDiv("stake");
            if (stake) {
                var isStakeValid = true;
                var stakeValue = parseFloat(_removeCommas(stake.value));
                if (stake.vlaue == '' || isNaN(parseFloat(stakeValue))) {
                    isStakeValid = false;
                }
                if (isStakeValid && flag == 1) {
                    apb.disabled = false;
                } else {
                    apb.checked = false;
                    apb.disabled = true;
                }
                if (flag == 1 && !apb.disabled && (apb.checked || aboCheckStatus)) {
                    stakeValue = parseInt(stakeValue, 10);
                    if (stakeValue < _syn.minBet) {
                        _onUpdateStake(parseFloat(_syn.minBet));
                        stake.value = _addCommas("" + _syn.minBet);
                        alert(_template['msg-adjust-stake-minbet'].getText());
                    } else if (stakeValue > _syn.maxBet) {
                        _onUpdateStake(parseFloat(_syn.maxBet));
                        stake.value = _addCommas("" + _syn.maxBet);
                        alert(_template['msg-adjust-stake-maxbet'].getText());
                    }
                    stake.disabled = true;
                    apb.checked = true;
                    _syn.isAutoAccept = true;
                    apb.focus();
                } else {
                    stake.disabled = false;
                }
            } else {
                apb.checked = false;
                apb.disabled = true;
            }
            apb.title = (apb.checked) ? _template['msg-disable-autobet'].getText() : _template['msg-enable-autobet'].getText();
        }
        return true;
    };
    var _hasDraw = false;

    function _clearSelectedOdds() {
        if (_ticketCache.isOddsChanged()) {
            return;
        }
        if (!_hasDraw) {
            if ($M('odds-display') && $M('odds-display').draw) {
                setTimeout(function () {
                    $M('odds-display').draw();
                }, 100);
            }
            _hasDraw = true;
        } else {
            if ($M('odds-display') && $M('odds-display').clearSelectedOdds) {
                $M('odds-display').clearSelectedOdds();
            }
        }
        if ($M('interested-event') && $M('interested-event').draw) {
            $M('interested-event').draw();
        }
        if ($M('live-sport-display') && $M('live-sport-display').draw) {
            $M('live-sport-display').draw();
        }
    }

    function _onCancelTicket() {
        _ticketCache.clearSingleOrder();
        _syn.isTicketOpened = false;
        _syn.isRefreshChecked = false;
        _onTicketTab();
        _ticketCache.updateHidRefreshOddParm('cancel');
        _submit();
        _clearSelectedOdds();
    };
    this.onSubmitTicket = function () {
        _onSubmitTicket(false, 0);
    };

    function _onSubmitTicket(isMP, isAuto) {
        if (_syn.isOrdProcessing) {
            alert(_template['msg-order-wait'].getText());
            return;
        }
        _syn.isOrdProcessing = true;
        var stakeDiv = _getDiv('stake');
        var adjustedStake = stakeDiv.value;
        var stake = _removeCommas(adjustedStake);
        var acceptIfAny = 0;
        var onlyAcceptBetterOdds = 0;
        var stakeInAuto = 0;
        var e1 = null;
        var e2 = null;
        if (!isMP) {
            var ano = _getDiv("tk:tk:acceptanyodds");
            if (ano && ano.checked) {
                acceptIfAny = 1;
            }
        }
        var isValid = false;
        if (stake && !isNaN(stake)) {
            try {
                stake = parseInt(stake, 10);
                if (stake <= 0) {
                    if (!isAuto) {
                        alert(_template['msg-stk-grt-zero'].getText());
                    }
                } else if (stake < _syn.minBet) {
                    adjustedStake = _addCommas("" + _syn.minBet);
                    if (!isAuto) {
                        alert(_template['msg-adjust-stake-minbet'].getText());
                    }
                } else if (stake > _syn.maxBet) {
                    adjustedStake = _addCommas("" + _syn.maxBet);
                    _calculatePO(adjustedStake);
                    if (!isAuto) {
                        alert(_template['msg-adjust-stake-maxbet'].getText());
                    }
                } else {
                    isValid = true;
                }
            } catch (e) {}
        } else if (!isAuto) {
            alert(_template['msg-pb-fmsg-2'].getText());
        }
        if (isValid && (isAuto || confirm(_template['msg-order-confirm'].getText()))) {
            if (isMP) {
                if (_ticketCache.getTotalMPBetCount() < _MixParlayMinCount) {
                    alert(_template['msg-mporder-min-req'].getText());
                    _syn.isOrdProcessing = false;
                    return;
                }
            } else {
                if (isAuto) {
                    onlyAcceptBetterOdds = 1;
                }
                stakeInAuto = "" + stake;
            }
            if (_rfTimeOutID) {
                _clearTimeOutRF();
            }
            var betpage = '';
            var betcount = isMP ? _ticketCache.getMPLastBetCount() : _ticketCache.getLastBetCount();
            var ostyle = isMP ? -1 : _ticketCache.getCurrentOrderOddsStyle();
            if (!isMP) {
                betpage = _ticketCache.getCurrentPage();
                _submitOrder(betcount, stake, ostyle, stakeInAuto, betpage, acceptIfAny);
            } else {
                _submitMPOrder(betcount, stake);
            }
            _getDiv("module-ticket").style.display = "none";
            _syn.isRefreshChecked = false;
        } else {
            if (!stakeDiv.disabled) {
                stakeDiv.focus();
            } else {
                var atp = _getDiv('tk:tk:autoprocess');
                if (atp && !atp.disabled) {
                    atp.focus();
                }
            }
            stakeDiv.value = adjustedStake;
            _calEstPO(stakeDiv.value);
            _syn.isOrdProcessing = false;
        }
        if (_syn.isOrdProcessing && _syn.ticket == 1) {
            _syn.isJustSubmitted = true;
        }
        return false;
    };

    function _onTicketTab() {
        _syn.isTicketClicked = false;
        _syn.isSameSport = 1;
        if (_syn.ticket == 1 && _syn.isTicketOpened) {
            _draw();
            $M('ticket').hideTicket();
            return;
        }
        _syn.ticket = 1;
        _draw();
        if (!_rfTimeOutID) {
            $M('ticket').onRefresh();
        }
    };

    function _onParlayTab() {
        _clearTimeOutRF();
        _syn.isTicketClicked = false;
        _syn.isSameSport = 1;
        if (_syn.ticket == 0 && _syn.isTicketOpened) {
            _draw();
            $M('ticket').hideTicket();
            return;
        }
        _syn.ticket = 0;
        _draw();
    };

    function _onMPRemoveOrder(key) {
        var param = '&id=' + key + '&mp_action=del';
        _submitMP(param);
    };

    function _onMPCancelTicket() {
        _ticketCache.clearParlayOrder();
        _syn.isTicketOpened = false;
        _submitMP('&mp_action=clear');
        _onParlayTab();
        _clearSelectedOdds();
    };
    this.onMPSubmitTicket = function () {
        _onSubmitTicket(true, 0);
    };

    function _getDisplaySetting(key) {
        if ($M('odds-display') && $M('odds-display').getDisplaySetting) {
            return $M('odds-display').getDisplaySetting(key);
        }
        if ($M('live-sport-display') && $M('live-sport-display').getDisplaySetting) {
            return $M('live-sport-display').getDisplaySetting(key);
        }
    }

    function _onOpenMixParlayOddsPage() {
        $M('odds-display').setDisplaySetting('market-page', 9);
        if ($M('slider-bar') && $M('slider-bar').draw) {
            $M('slider-bar').draw();
        }
        if ($M('odds-display-setting') && $M('odds-display-setting').draw) {
            $M('odds-display-setting').draw();
        }
    }

    function _getLatestMPCount() {
        var cntDiv = _getDiv('tk:mp:gotomp:mpcnt');
        if (cntDiv) {
            cntDiv.innerHTML = $M('sport-market').getTotalParlayCount();
        }
    }

    function _calEstPO(s) {
        var stake = parseInt(s.replace(/,/g, ""), 10);
        if (isNaN(stake)) {
            _getDiv('tk:payout').innerHTML = '0';
            return;
        } else {
            _getDiv('stake').className = 'stake-input';
        }
        var po;
        _onUpdateStake(stake);
        if (_syn.isOddsConStake) {
            if (_syn.ticketOdds < 0) {
                po = stake * 2;
            } else if (_syn.ticketOdds < 1) {
                po = stake * _syn.ticketOdds + stake;
            } else {
                if (_ticketCache.getCurrentOrderOddsStyle() == 4) {
                    po = stake * _syn.ticketOdds;
                } else {
                    po = stake * _syn.ticketOdds + stake;
                }
            }
        } else {
            po = stake * _syn.ticketOdds;
        }
        var ter = _exRate - 0;
        var isCSType = parseInt(_ticketCache.getCurrentMarketType(), 10) == 4 || parseInt(_ticketCache.getCurrentMarketType(), 10) == 14 ? true : false;
        if (!isNaN(ter)) {
            if ((_syn.ticket == 1 && isCSType) || (_syn.ticket == 0)) {
                if (_syn.isSameSport != undefined) {
                    frate = Math.round(100000 / ter);
                    hrate = Math.round(20000 / ter);
                    if ((isCSType || _syn.isSameSport == 1) && po > frate) {
                        po = frate;
                    }
                    if (_syn.isSameSport == 0 && po > hrate) {
                        po = hrate;
                    }
                }
            }
        }
        _getDiv('tk:payout').innerHTML = _addCommas(String((Math.round(parseFloat((po * 100).toFixed(6))) / 100).toFixed(2)));
    }

    function _calculatePO(st) {
        var n = _getDiv('stake').value.replace(/,/g, "");
        st.value = _addCommas(n);
        _calEstPO(n);
    }

    function resetPO(eid) {
        var a = _getDiv(eid);
        if (a) a.innerHTML = '0';
    }

    function _getDOddsPrice(pr) {
        var price = parseFloat(pr);
        switch (_syn.oddsEncVersion) {
        case 0:
        default:
            return price;
        case 1:
            return price + 0.03;
        case 2:
            return price + 0.04;
        case 3:
            return price + 0.05;
        case 4:
            return price + 0.06;
        case 5:
            return price + 0.07;
        case 6:
            return price + 0.08;
        }
    }
    this.draw = function () {
        _draw(false);
    };

    function _draw(isReceipt) {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        _drawTicketDivOnly(isReceipt);
        _syn.isTicketOpened = true;
        if (!isReceipt) {
            if (_syn.ticket == 1) {
                var ediv = _getDiv("tk:tk:error");
                if (ediv) {
                    ediv.style.display = "none";
                }
                _onAutoProcessBet(_syn.isFirstTimeDraw ? 0 : 1);
                _ticketCache.resetOldOddsValue();
                _ticketCache.resetOldHDPScoreInfo();
            } else {
                _syn.isFromTicket = false;
            }
        }
        if ($M('global') && $M('global').scrollDivMyBet) {
            $M('global').scrollDivMyBet(true);
        }
    }
    var _oldOddId = 0;
    var _oldOddOption = 0;

    function _drawTicketDivOnly(isReceipt) {
        var auto = _getDiv("tk:tk:autoprocess");
        _syn.isAutoCheckedBeforeDraw = auto && auto.checked ? true : false;
        var div = _getDiv("module-ticket");
        if (div) {
            var resp = $M('live-sport-display') ? _getLSPageTicketContent(isReceipt) : _getContent(isReceipt);
            if (_ticketCache.getSimpleOddsId() == _oldOddId && _ticketCache.getSimpleOddsOption() == _oldOddOption) {
                var sdiv = _getDiv('stake');
                if (sdiv) {
                    var stakeStr = sdiv.value;
                    if (stakeStr) {
                        var stake = parseInt(stakeStr.replace(/,/g, ""), 10);
                        _onUpdateStake(stake);
                    }
                }
            } else {
                _oldOddId = _ticketCache.getSimpleOddsId();
                _oldOddOption = _ticketCache.getSimpleOddsOption();
            }
            div.innerHTML = resp;
            div.style.display = "";
            if ($M('mini-bet-list') && $M('mini-bet-list').show) {
                if ((_syn.ticket == 1 && !_ticketCache.isAnySingleOrder()) || (_syn.ticket == 0 && _ticketCache.getTotalMPBetCount() == 0)) {
                    $M('mini-bet-list').show();
                } else {
                    $M('mini-bet-list').hide();
                }
            }
            if (!$M('live-sport-display')) {
                if ($M('sport-market')) {
                    try {
                        $M('sport-market').hideSportMarket();
                    } catch (err) {}
                }
            } else {
                if (_ticketCache.isAnySingleOrder()) {
                    if (!_ticketCache.isLiveTicket()) {
                        div.className = 'ticket-mp-block';
                    } else {
                        div.className = 'ticket-mp-block live';
                    }
                } else {
                    div.className = 'ticket-mp-block live';
                }
            }
        }
        if (_syn.isRefreshChecked) {
            var rf = _getDiv("tk:tk:autorefresh");
            if (rf) {
                rf.checked = true;
                if (_syn.isFirstTimeDraw) {
                    _clearTimeOutRF();
                    $M('ticket').onRefresh();
                }
            }
        } else {
            var rfL = _getDiv("tk:tk:autorefreshLbl");
            if (rfL) {
                rfL.className = 'ticket-refresh';
                rfL.innerHTML = '';
            }
        }
        var flag = 0;
        var sdiv = _getDiv('stake');
        if (sdiv && _getTicketStake() > 0) {
            sdiv.value = _addCommas(_getTicketStake().toString());
            _calEstPO(_getTicketStake().toString());
            flag = 1;
            _setResetStakeWord(1);
        };
        if (sdiv) {
            if (sdiv.focus) {
                sdiv.focus();
            }
            if (sdiv.setSelectionRange) {
                var len = sdiv.value.length;
                sdiv.setSelectionRange(len, len);
            } else if (sdiv.createTextRange) {
                var range = sdiv.createTextRange();
                range.moveStart('character', sdiv.value.length);
                range.collapse();
                range.select();
            } else {
                sdiv.value = sdiv.value;
            }
        }
        if (!flag) {
            _setResetStakeWord(0, 1);
        }
        _checkBetterOddsOption();
    }

    function _drawErrorResponse(errorNo) {
        if (_syn.ticket == 1) {
            _draw(false);
            var ediv = _getDiv("tk:tk:error");
            if (ediv) {
                ediv.innerHTML = _template['msg-pb-freason-' + errorNo].getText();
                ediv.style.display = "";
            }
        }
    }

    function _getLSPageTicketContent(isReceipt) {
        var d = {};
        d['tc-cls-selected'] = 'selected';
        d['tc-cls-hide'] = '';
        if (isReceipt) {
            d['ticket-body-data'] = _getSimpleTicketReceipt();
            d['parlay-body-data'] = '';
            return _template['ls-ticket-display'].getText(d);
        }
        d['cls-live'] = _ticketCache.isLiveTicket() ? 'live' : '';
        d['ticket-body-data'] = _getSimpleTicketBodyData();
        return _template['ls-ticket-display'].getText(d);
    }

    function _getContent(isReceipt) {
        var d = {};
        _syn.ticketOdds = _syn.ticket == 1 ? _getDOddsPrice(_ticketCache.getSimpleOddsValue()) : parseFloat(_ticketCache.getMPOddsValue());
        d['tc-cls-selected'] = _syn.ticket == 1 ? 'selected' : '';
        d['mp-cls-selected'] = _syn.ticket != 1 ? 'selected' : '';
        d['total-mp-order'] = _ticketCache.getTotalMPBetCount();
        d['tc-cls-hide'] = _syn.ticket == 1 ? '' : 'hide';
        d['mp-cls-hide'] = _syn.ticket != 1 ? '' : 'hide';
        if (isReceipt) {
            d['ticket-body-data'] = _getSimpleTicketReceipt();
            d['parlay-body-data'] = '';
            return _template['ticket-display'].getText(d);
        }
        d['cls-live'] = _syn.ticket == 1 ? (_ticketCache.isLiveTicket() ? 'live' : '') : '';
        d['ticket-body-data'] = _syn.ticket == 1 ? _getSimpleTicketBodyData() : '';
        d['parlay-body-data'] = _syn.ticket == 1 ? '' : _getParleyBodyData();
        return _template['ticket-display'].getText(d);
    }

    function _getSimpleTicketReceipt() {
        var d = {};
        var data = _ticketCache.getSingleOrderData();
        d['sportsName'] = data[_ticketDataIdx.sportType];
        d['MarketName'] = data[_ticketDataIdx.marketName];
        d['ht-cls-red-blue'] = data[_ticketDataIdx.hdpType] == 1 ? "Red" : "Blue";
        d['homeTeamName'] = data[_ticketDataIdx.homeTeam];
        d['aw-cls-red-blue'] = data[_ticketDataIdx.hdpType] == 2 ? "Red" : "Blue";
        d['awayTeamName'] = data[_ticketDataIdx.awayTeam];
        d['TournamentName'] = data[_ticketDataIdx.tournamentName];
        d['NewBetTypeGroupName'] = data[_ticketDataIdx.betTypeGrName];
        d['referenceNo'] = _siReceipt.refNO;
        if (_siReceipt.isHdpPoint == 1) {
            d['handicapPoint'] = _siReceipt.hdpPoint;
            d['handicapInfo'] = _template['simple-tc-rc-handicap'].getText(d);
        } else {
            d['handicapInfo'] = '';
        }
        d['score'] = _getColonTemplate(_siReceipt.score);
        d['price'] = _siReceipt.price;
        d['oddsChoice'] = _siReceipt.oddsChoice;
        d['currency'] = '';
        d['stake'] = _addCommas('' + _siReceipt.stake);
        d['status'] = _siReceipt.status;
        d['winAmount'] = _siReceipt.winAmount;
        d['point'] = _siReceipt.totalGoal;
        if (_siReceipt.tmplType == 'or') {
            d['team-name-info'] = '';
            d['scorePointInfo'] = '';
        } else {
            d['team-name-info'] = _template['simple-tk-team-name'].getText(d);
            if (_siReceipt.betType == 3 || _siReceipt.betType == 9) {
                d['scorePointInfo'] = _template['simple-tc-rc-point'].getText(d);
            } else {
                d['scorePointInfo'] = _template['simple-tc-rc-score'].getText(d);
            }
        }
        return _template['simple-ticket-receipt'].getText(d);
    }

    function _getSimpleTicketBodyData() {
        var data = _ticketCache.getSingleOrderData();
        var d = {};
        if (_syn.invalidOddsErr) {
            if (_syn.invalidOddsErr != 0 && _syn.invalidOddsErr != 999) {
                d['odds-error-msg'] = _template['msg-pb-fmsg-' + _syn.invalidOddsErr].getText();
                _syn.invalidOddsErr = 0;
                return _template['odds-error-msg'].getText(d);
            } else if (_syn.invalidOddsErr == 999) {
                _syn.invalidOddsErr = 0;
                return _template['odds-closed-msg'].getText();
            }
        }
        if (!_ticketCache.isAnySingleOrder()) {
            return _template['no-bet-msg'].getText();
        }
        _updateSynAttributes(data);
        d['sportsName'] = data[_ticketDataIdx.sportType];
        d['MarketName'] = data[_ticketDataIdx.marketName];
        d['ht-cls-red-blue'] = data[_ticketDataIdx.hdpType] == 1 ? "Red" : "Blue";
        d['homeTeamName'] = data[_ticketDataIdx.homeTeam];
        d['aw-cls-red-blue'] = data[_ticketDataIdx.hdpType] == 2 ? "Red" : "Blue";
        d['awayTeamName'] = data[_ticketDataIdx.awayTeam];
        d['TournamentName'] = TiLib.Text.encodeHTML(data[_ticketDataIdx.tournamentName]);
        var hdpPointScoreInfo = data[_ticketDataIdx.HDP];
        d['NewBetTypeGroupName'] = data[_ticketDataIdx.betTypeGrName];
        var mktType = data[_ticketDataIdx.marketType];
        if (mktType == 1 || mktType == 7) {
            d['betOptionName'] = data[_ticketDataIdx.betTeam];
            if (data[_ticketDataIdx.betOption] == 'h') {
                d['opt-cls-red-blue'] = data[_ticketDataIdx.hdpType] == 1 ? "Red" : "Blue";
            } else {
                d['opt-cls-red-blue'] = data[_ticketDataIdx.hdpType] == 2 ? "Red" : "Blue";
            }
        } else {
            if (mktType == 4 || mktType == 14) {
                data[_ticketDataIdx.betOption] = _getColonTemplate(data[_ticketDataIdx.betOption]);
            }
            d['betOptionName'] = data[_ticketDataIdx.betOption] == '' ? data[_ticketDataIdx.betTeam] : data[_ticketDataIdx.betOption];
            d['opt-cls-red-blue'] = _marketTypeInBlueForOption.indexOf(':' + mktType + ':') > -1 ? "Blue" : "Red";
        }
        if (_ticketCache.isCurrentOddsIsMP()) {
            d['simple-tc-addmp'] = _template['simple-tc-addmp'].getText();
        } else {
            d['simple-tc-addmp'] = '';
        }
        if (_ticketCache.isOROrder()) {
            d['team-name-info'] = '';
            d['hdp-point-info'] = '';
        } else {
            d['team-name-info'] = _template['simple-tk-team-name'].getText(d);
            if (hdpPointScoreInfo) {
                if (hdpPointScoreInfo.length > 1) {
                    d['hdpInfo'] = hdpPointScoreInfo[0];
                    d['score-class'] = _ticketCache.isScoreChanged() ? 'score-change' : '';
                    d['home-score'] = hdpPointScoreInfo[1];
                    d['away-score'] = hdpPointScoreInfo[2];
                    if (hdpPointScoreInfo[0] && hdpPointScoreInfo[0] != '') {
                        d['hdp-point-info'] = _template['simple-tk-hdpinfo-score-a'].getText(d);
                    } else {
                        d['hdp-point-info'] = _template['simple-tk-hdpinfo-score'].getText(d);
                    }
                } else {
                    d['hdpPointInfo'] = hdpPointScoreInfo[0];
                    d['hdp-point-info'] = _template['simple-tk-hdpinfo'].getText(d);
                }
            } else {
                d['hdp-point-info'] = '';
            }
        }
        d['betCondition'] = data[_ticketDataIdx.betCondition] == '' ? '' : _getBetConditionContent(data[_ticketDataIdx.betCondition]);
        var price = data[_ticketDataIdx.oddsValue];
        d['cls-price-red'] = price > 0 ? '' : 'Red';
        var oddsPrice = _getDOddsPrice(price);
        d['orderPrice'] = TiLib.Number.toString(oddsPrice, 3, 2);
        d['userCurrency'] = '';
        d['minAmount'] = _addCommas('' + data[_ticketDataIdx.minBet]);
        d['maxAmount'] = _addCommas('' + data[_ticketDataIdx.maxBet]);
        d['oddsRefreshRate'] = _syn.isFirstTimeDraw ? _syn.oddsRefreshRate : _syn.oddsRefreshCount;
        d['double-promotion-disclaimer'] = data[_ticketDataIdx.isDoublePromo] ? _template['double-promotion-disclaimer'].getText() : '';
        if (_ticketCache.isOddsChanged()) {
            d['cls-odds-change'] = 'odds-change';
            if (_ticketCache.isBetterOdds()) {
                d['cls-price-down'] = 'price-up';
            } else {
                d['cls-price-down'] = 'price-down';
            }
        } else {
            d['cls-odds-change'] = '';
            d['cls-price-down'] = '';
        }
        d['odds-section'] = _template['simple-ticket-odd-section'].getText(d);
        d['autorefresh-title'] = _syn.isRefreshChecked ? _template['msg-tk-disable-refresh'].getText() : _template['msg-tk-enable-refresh'].getText();
        return _template['simple-ticket-body'].getText(d);
    }

    function _getColonTemplate(stringD) {
        while (1) {
            if (stringD.indexOf('##') > -1) {
                var colonTmpl = _template['hdpinfo-colon'].getText();
                stringD = stringD.replace("##", colonTmpl);
            } else {
                break;
            }
        }
        return stringD;
    }

    function _getBetConditionContent(betCondition) {
        var data = betCondition.split(',');
        var sb = [];
        for (var i = 0; i < data.length; i++) {
            sb.push(' <span class="NW">');
            sb.push(data[i]);
            if ((i + 1) == data.length) {
                sb.push('</span>');
            } else {
                sb.push(',</span>');
            }
        }
        var d = {};
        d['betConditionData'] = sb.join('');
        return _template['simple-ticket-bet-condition'].getText(d)
    }

    function _updateSynAttributes(data) {
        _syn.ticketOdds = _getDOddsPrice(data[_ticketDataIdx.oddsValue]);
        _ticketCache.updateDecryptedOddsVal(_syn.ticketOdds);
        _syn.minBet = parseFloat(data[_ticketDataIdx.minBet]);
        _syn.maxBet = parseFloat(data[_ticketDataIdx.maxBet]);
        _syn.isOddsConStake = data[_ticketDataIdx.isOddsConStake];
        if (data[_ticketDataIdx.autoRfOddsOpt] == "True") {
            _syn.isRefreshChecked = true;
        } else {
            _syn.isRefreshChecked = false;
        }
        if (data[_ticketDataIdx.autoAcctOddsOpt] == "True") {
            _syn.isAutoAcceptBetterOdds = true;
        } else {
            _syn.isAutoAcceptBetterOdds = false;
        }
        if (parseInt(data[_ticketDataIdx.isLive], 10) == 1) {
            _syn.oddsRefreshRate = 5;
        } else {
            _syn.oddsRefreshRate = 9;
        }
        if (_syn.isFirstTimeDraw) {
            _syn.oddsRefreshCount = _syn.oddsRefreshRate;
        }
    }

    function _resetAcceptOddsCondition() {
        _syn.isAutoAcceptBetterOdds = false;
        _syn.isAnyOddsAccept = false;
        _syn.isAutoAccept = false;
    }

    function _checkBetterOddsOption() {
        if (_syn.ticket != 1) {
            return;
        }
        var abo = _getDiv("tk:tk:acceptbetterodds");
        if (abo && _syn.isAutoAcceptBetterOdds) {
            abo.checked = true;
        } else {
            if (abo && !_syn.isAutoAcceptBetterOdds) {
                abo.checked = false;
            }
            var any = _getDiv("tk:tk:acceptanyodds");
            if (any && _syn.isAnyOddsAccept) {
                any.checked = true;
            } else if (any && !_syn.isAnyOddsAccept) {
                any.checked = false;
            }
        }
    }

    function _getParleyBodyData() {
        var d = {};
        if (_syn.invalidOddsErr && _syn.invalidOddsErr != 0) {
            if (_syn.invalidOddsErr == 999) {
                _syn.invalidOddsErr = 0;
                return _template['odds-closed-msg'].getText();
            } else {
                d['odds-error-msg'] = _template['msg-pb-fmsg-' + _syn.invalidOddsErr].getText();
                _syn.invalidOddsErr = 0;
                return _template['odds-error-msg'].getText(d);
            }
        }
        if (_ticketCache.getTotalMPBetCount() == 0) {
            var totParlayCount = $M('sport-market').getTotalParlayCount();
            d['totalParlayCount'] = totParlayCount;
            return _template['mp-no-bet-msg'].getText(d)
        }
        var data = _ticketCache.getMPOrderData();
        d['mp-order-row'] = _getMPOrderRows(data[_mpDataIdx.orders]);
        d['userCurrency'] = '';
        d['mix-parlay-price'] = data[_mpDataIdx.oddsValue];
        _syn.minBet = parseFloat(data[_mpDataIdx.minBet]);
        _syn.maxBet = parseFloat(data[_mpDataIdx.maxBet]);
        d['minAmount'] = _addCommas('' + data[_mpDataIdx.minBet]);
        d['maxAmount'] = _addCommas('' + data[_mpDataIdx.maxBet]);
        d['double-promotion-disclaimer'] = data[_mpDataIdx.isDoublePromo] ? _template['double-promotion-disclaimer'].getText() : '';
        return _template['parlay-ticket-body'].getText(d);
    }

    function _getMPOrderRows(rows) {
        var sb = [];
        var len = rows.length;
        for (var idx = 0; idx < len; idx++) {
            var row = rows[idx];
            var d = {};
            d['homeTeamName'] = row[_mpOrderIdx.homeTeam];
            d['ht-cls-red-blue'] = row[_mpOrderIdx.hdpType] == 1 ? "Red" : "Blue";
            d['awayTeamName'] = row[_mpOrderIdx.awayTeam];
            d['aw-cls-red-blue'] = row[_mpOrderIdx.hdpType] == 2 ? "Red" : "Blue";;
            d['marketTypeName'] = row[_mpOrderIdx.marketName];
            d['hdpPointInfo'] = row[_mpOrderIdx.hdpType];
            d['betOptionName'] = row[_mpOrderIdx.betOption];
            d['orderPrice'] = row[_mpOrderIdx.oddsValue];
            d['dictKey'] = row[_mpOrderIdx.eventId];
            d['sportsName'] = row[_mpOrderIdx.sportsFName];
            sb.push(_template['mp-order-row-data'].getText(d));
            if (row[_mpOrderIdx.sportsName] != 'FTB') {
                _syn.isSameSport = 0;
            }
        }
        return sb.join('');
    };
    this.resetOProcessing = function () {
        _syn.isOrdProcessing = false;
    }
    this.onMPErrorDraw = function (errCode, lastBetCount) {
        _syn.isOrdProcessing = false;
        if (lastBetCount) {
            _ticketCache.updateMPLastBetCount(lastBetCount);
        }
        errCode = ((errCode >= 2 && errCode <= 10) || (errCode >= 50 && errCode <= 51)) ? errCode : 3;
        var div = _getDiv("module-ticket");
        if (div) {
            var d = {};
            d['tc-cls-selected'] = '';
            d['mp-cls-selected'] = 'selected';
            d['total-mp-order'] = 0;
            d['tc-cls-hide'] = 'hide';
            d['mp-cls-hide'] = '';
            d['cls-live'] = '';
            d['ticket-body-data'] = '';
            d['odds-error-msg'] = _template['msg-pb-freason-' + errCode].getText();
            d['parlay-body-data'] = _template['odds-error-msg'].getText(d);
            div.innerHTML = _template['ticket-display'].getText(d);
            div.style.display = "";
            if (!$M('live-sport-display')) {
                if ($M('sport-market')) {
                    $M('sport-market').hideSportMarket();
                }
            }
        }
        _resetTicketCache(0);
        if ($M('global') && $M('global').scrollDivMyBet) {
            $M('global').scrollDivMyBet(true);
        }
    }

    function _addCommas(str) {
        var b = str.split(".");
        var n = b[0];
        var a = [];
        while (n.length > 3) {
            var nn = n.substr(n.length - 3);
            a.unshift(nn);
            n = n.substr(0, n.length - 3);
        }
        if (n.length > 0) {
            a.unshift(n);
        }
        n = a.join(',');
        if (b.length == 2)
            n += "." + b[1];
        return n;
    }

    function _removeCommas(strValue) {
        return strValue.replace(/,/g, '');
    }

    function _getDiv(id) {
        return document.getElementById(id);
    }

    function _clearTimeOutRF() {
        clearTimeout(_rfTimeOutID);
        _rfTimeOutID = 0;
    }
}

function __Module_MiniBetList(loginName, refreshRate, runningBetRefreshRate) {
    var _TemplateName = 'betlist/mini-bet-list';
    var _self = this;
    var _template = null;
    var _loginName = loginName;
    var _syn = {
        isOrdProcessing: false,
        simpleBets: 0,
        orBets: 1,
        mpBets: 2,
        noOfCurrRow: 0,
        blRefreshRate: refreshRate,
        blRefreshCounter: 0,
        waitingRefreshRate: refreshRate,
        runningRefreshRate: runningBetRefreshRate,
        resetRFCounter: false,
        cooldownCount: 0,
        waitingTotal: 0,
        runningTotal: 0
    };
    var _betStatus = {
        running: 1,
        waiting: 2,
        rejected: 6,
        voided: 7,
        refunded: 8
    };
    var _waitingBets = [];
    var _runningBets = [];
    var _maxNoOfRows = 0;
    var _blTimeOutID = 0;
    var _blFirstTimeDraw = 0;
    var _drawFull = true;
    var _isHidden = false;
    this.initiate = function () {
        TiLib.Timer.addToSecondTimer(_self);
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        this.openBetlistMini();
    };
    this.onUpdate = function (data, maxRows) {
        if (data) {
            var oldTotalNoOfOrder = _waitingBets.length + _runningBets.length;
            var oldWaitingNoOfOrder = _waitingBets.length;
            _waitingBets = [];
            _runningBets = [];
            var waitingBets = data[0];
            var runningBets = data[1];
            if (waitingBets) {
                _waitingBets = waitingBets;
            }
            if (runningBets) {
                _runningBets = runningBets;
            }
            if (maxRows) {
                _maxNoOfRows = maxRows;
            }
            var totalOrder = _waitingBets.length + _runningBets.length;
            if (totalOrder < 1 || (oldTotalNoOfOrder < 1 && totalOrder > 0) || (_waitingBets.length < 1) || (oldWaitingNoOfOrder < 1 && _waitingBets.length > 0)) {
                _blFirstTimeDraw = 0;
            }
            _syn.resetRFCounter = true;
            _draw();
            _syn.resetRFCounter = false;
            _clearTimeOutID();
            if ((_syn.runningTotal + _syn.waitingTotal) > 0) {
                this.betListTimer();
            }
        }
    };
    this.openBetlistMini = function () {
        _submit();
        _syn.cooldownCount = 1;
        _drawRefreshButtons();
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_syn.waitingTemplate) {
                    if (_template) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                }
            }
        }
    };
    this.onIdle = function () {};
    this.betListTimer = function () {
        if (_syn.cooldownCount) {
            _drawRefreshButtons();
            _syn.cooldownCount--;
        } else {
            if (_syn.blRefreshCounter == 0) {
                _clearTimeOutID();
                _syn.blRefreshCounter = _syn.waitingTotal > 0 ? _syn.blRefreshRate : _syn.runningRefreshRate;
                _syn.cooldownCount = 1;
                _drawRefreshButtons();
                if ((_syn.waitingTotal || _syn.runningTotal) > 0) {
                    _submit();
                }
            } else {
                _drawRefreshButtons();
                _syn.blRefreshCounter--;
            }
        }
        _blTimeOutID = setTimeout('$M(\'mini-bet-list\').betListTimer()', 1000);
    };
    this.onMouseOver = function (event, name) {
        if (name != 'mb:rf') {
            return;
        }
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            if (!id) return true;
            if (id == 'mb:rf:button') {
                if (!e.isHover) {
                    e.isHover = true;
                    _drawRefreshButtons();
                }
                return false;
            }
            e = e.parentNode;
        }
        return true;
    };
    this.onMouseOut = function (event, name) {
        if (name != 'mb:rf') {
            return;
        }
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            if (!id) return true;
            if (id == 'mb:rf:button') {
                if (e.isHover) {
                    e.isHover = false;
                    setTimeout(function () {
                        _drawRefreshButtons()
                    }, 250);
                }
                return false;
            }
            e = e.parentNode;
        }
        return true;
    };

    function _submit(param) {
        var sb = [];
        sb.push('/web-root/restricted/betlist/bet-list-mini-data.aspx?');
        if (param) {
            sb.push(param);
        }
        if (_blTimeOutID) {
            _clearTimeOutID();
        };
        return TiLib.Ajax.sendRequest('mini-bet-list', sb.join(''));
    }

    function _clearTimeOutID() {
        clearTimeout(_blTimeOutID);
        _blTimeOutID = 0;
    }
    this.onTime = function () {
        if (!_blTimeOutID) {
            if (_syn.cooldownCount) {
                _syn.cooldownCount--;
                _drawRefreshButtons();
            } else {
                if ((_syn.runningTotal + _syn.waitingTotal) > 0) {
                    this.betListTimer();
                }
            }
        }
    };
    this.onClick = function (event) {
        if (!_onMyBetsClick(event)) {
            event.returnValue = false;
            return false;
        };
    }

    function _onMyBetsClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'mb:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 1) {
                if (atom[0] == 'mb') {
                    if (atom[1] == 'rf' && atom[2] == 'button') {
                        _self.onRefresh();
                        return false;
                    } else if (atom[1] == 'viewall') {
                        _callToTopBannerMyBets();
                    } else if (atom[1] == 'rm' && atom[2] == '1') {
                        _removeRejectedBets(atom[3]);
                    } else if (atom[1] == 'toggle') {
                        if (_isHidden) {
                            var force = true;
                            _self.show(force);
                        } else {
                            if ($M('global') && $M('global').isSmallScreen) {
                                if (!$M('global').isSmallScreen()) {
                                    var force = true;
                                    _self.hide(force);
                                } else {
                                    if ($M('ticket') && $M('ticket').show) {
                                        $M('ticket').show();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    this.onSetResetFullDraw = function (flag) {
        _drawFull = flag;
        _draw();
    }
    this.show = function (force) {
        if ($M('global') && $M('global').isSmallScreen) {
            if ($M('global').isSmallScreen() || force) {
                _isHidden = false;
                _submit();
            }
        }
    }
    this.hide = function (force) {
        if ($M('global') && $M('global').isSmallScreen) {
            if ($M('global').isSmallScreen() || force) {
                _isHidden = true;
                var div = document.getElementById("mb:pb:data");
                if (div) {
                    div.parentNode.removeChild(div);
                }
                _draw();
                _clearTimeOutID();
            }
        }
    }
    this.onRefresh = function () {
        if (_syn.cooldownCount) {
            return;
        }
        _clearTimeOutID();
        _syn.blRefreshCounter = _syn.waitingTotal > 0 ? _syn.blRefreshRate : _syn.runningRefreshRate;
        _syn.cooldownCount = 1;
        _drawRefreshButtons();
        _submit();
    };

    function _callToTopBannerMyBets() {
        $M('page-head').onMyBetsClick();
    }

    function _draw() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        if (!_blFirstTimeDraw) {
            var div = document.getElementById("module-mybets");
            if (div) {
                _syn.noOfCurrRow = 0;
                var resp = _getContent();
                div.innerHTML = resp;
                _blFirstTimeDraw = 1;
            }
        } else {
            var div = document.getElementById("mb:pb");
            if (div) {
                _syn.noOfCurrRow = 0;
                var resp = _getContent();
                div.innerHTML = resp;
            } else {
                _blFirstTimeDraw = 0;
                var div = document.getElementById("module-mybets");
                if (div) {
                    _syn.noOfCurrRow = 0;
                    var resp = _getContent();
                    div.innerHTML = resp;
                    _blFirstTimeDraw = 1;
                }
            }
        }
        if (_isHidden) {
            var div = document.getElementById("mb:pb:data");
            if (div) {
                div.parentNode.removeChild(div);
            }
        } else if ($M('ticket') && $M('ticket').hide) {
            $M('ticket').hide();
        }
        var div = document.getElementById('l-refresh-button-container');
        if (div) {
            if (_isHidden) {
                div.className = TiLib.Text.addClassItem(div.className, 'hide');
            } else if (_syn.waitingTotal == 0 && _syn.runningTotal == 0) {
                _drawRefreshButtons();
            } else {
                div.className = TiLib.Text.removeClassItem(div.className, 'hide');
                _drawRefreshButtons();
            }
        }
        if ($M('global') && $M('global').scrollDivMyBet) {
            $M('global').scrollDivMyBet();
        }
    }

    function _getHiddenContent() {
        var content = '';
        if (_template && _isHidden) {
            content = _template['mybets-display-hidden'].getText();
        }
        return content;
    }

    function _getContent() {
        var d = {};
        var resp = '';
        _syn.runningTotal = 0;
        _syn.waitingTotal = 0;
        var processed = false;
        if (!_isHidden) {
            if (_runningBets.length == 0) {
                var onlyWaitingBets = _waitingBets.length;
                for (var i = 0; i < _waitingBets.length; i++) {
                    if (_isTransIdIsInRemoved(_waitingBets[i][1])) {
                        onlyWaitingBets--;
                    }
                }
                if (onlyWaitingBets == 0) {
                    resp = _template['bet-list-with-no-data'].getText();
                    processed = true;
                }
            }
            if (!processed) {
                d['pending-bet-block'] = _waitingBets.length == 0 ? '' : _getPendingOrders();
                d['running-bet-block'] = _runningBets.length == 0 ? '' : _getRunningOrders();
                resp = _template['bet-list-with-data'].getText(d);
            }
        }
        if (_syn.resetRFCounter) {
            _syn.blRefreshCounter = _syn.waitingTotal > 0 ? _syn.blRefreshRate : _syn.runningRefreshRate;
            _syn.resetRFCounter = false;
        }
        if (!_blFirstTimeDraw) {
            d['bet-list-data'] = resp;
            return _template['mybets-display'].getText(d);
        } else {
            return resp;
        }
    }

    function _getPendingOrders() {
        var d = {};
        var sb = [];
        var rows = 0;
        if (_drawFull) {
            rows = _waitingBets.length;
        } else {
            rows = 1;
        }
        for (var i = 0; i < rows; i++) {
            if (_syn.noOfCurrRow >= _maxNoOfRows) {
                break;
            }
            if (_isTransIdIsInRemoved(_waitingBets[i][1])) {
                continue;
            }
            sb.push(_getOrdersRow(_waitingBets[i], true, false));
            _syn.noOfCurrRow += 1;
        }
        d['pending-bet-row'] = sb.join('');
        return _template['pending-bet-data'].getText(d);
    }

    function _getOrdersRow(row, isWaiting, isOdd) {
        var type = row[0];
        var dr = {};
        dr['orderTransId'] = row[1];
        dr['orderTransTime'] = row[2];
        dr['mktTypeShortName'] = row[4];
        dr['stake'] = addCommas('' + row[5]);
        dr['status'] = row[6];
        var cls = isOdd ? 'odd' : '';
        dr['cls-pending-bets'] = isWaiting ? 'pending-bets' : cls;
        if (type == _syn.simpleBets) {
            dr['sports'] = row[7];
            dr['TournamentName'] = TiLib.Text.encodeHTML(row[8]);
            dr['homeTeamName'] = row[9];
            dr['awayTeamName'] = row[10];
            dr['betOptionName'] = _getColonTemplate(row[11]);
            dr['orderPrice'] = row[12];
            dr['orderStyle'] = row[13];
            dr['betCondition'] = row[15] == '' ? '' : _getBetConditionContent(row[15]);
            dr['rejecetdStatus'] = 0;
            dr['NewBetTypeGroupName'] = row[16];
            var ostatus = parseInt(row[14], 10);
            if (ostatus == _betStatus.rejected) {
                dr['rejecetdStatus'] = 1;
                dr['bet-rejected-remove-icon'] = _template['bet-rejected-div'].getText(dr);
                dr['cls-strike-through'] = 'strike-through';
            } else if (ostatus == _betStatus.voided) {
                dr['bet-rejected-remove-icon'] = '';
                dr['cls-strike-through'] = 'strike-through';
            } else {
                dr['bet-rejected-remove-icon'] = '';
                dr['cls-strike-through'] = '';
                _calcTotalWaitingRunning(ostatus);
            }
            dr['home-away-team-info'] = _template['home-away-team-info-sec'].getText(dr);
            dr['order-stake-status-info'] = _template['order-stake-status-info'].getText(dr);
            dr['orderDetails'] = _template['order-details-data'].getText(dr);
            return _template['bet-row-data'].getText(dr);
        } else if (type == _syn.orBets) {
            dr['mktTypeShortName'] = 'OR';
            dr['sports'] = row[7];
            dr['TournamentName'] = TiLib.Text.encodeHTML(row[8]);
            dr['home-away-team-info'] = '';
            dr['betOptionName'] = row[9];
            dr['orderPrice'] = row[10];
            dr['rejecetdStatus'] = 0;
            dr['orderStyle'] = row[12];
            dr['NewBetTypeGroupName'] = row[13];
            var ostatus = parseInt(row[11], 10);
            if (ostatus == _betStatus.rejected) {
                dr['rejecetdStatus'] = 1;
                dr['bet-rejected-remove-icon'] = _template['bet-rejected-div'].getText(dr);
                dr['cls-strike-through'] = 'strike-through';
            } else if (ostatus == _betStatus.voided) {
                dr['bet-rejected-remove-icon'] = '';
                dr['cls-strike-through'] = 'strike-through';
            } else {
                dr['bet-rejected-remove-icon'] = '';
                dr['cls-strike-through'] = '';
                _calcTotalWaitingRunning(ostatus);
            }
            dr['order-stake-status-info'] = _template['order-stake-status-info'].getText(dr);
            dr['orderDetails'] = _template['order-details-data'].getText(dr);
            return _template['bet-row-data'].getText(dr);
        } else if (type == _syn.mpBets) {
            var bets = row[7];
            var clsStrikeThrough = '';
            var ostatus = parseInt(row[8], 10);
            dr['rejecetdStatus'] = 0;
            if (ostatus == _betStatus.rejected) {
                dr['rejecetdStatus'] = 1;
                dr['bet-rejected-remove-icon'] = _template['bet-rejected-div'].getText(dr);
                dr['cls-strike-through'] = 'strike-through';
                clsStrikeThrough = 'strike-through';
            } else if (ostatus == _betStatus.voided) {
                dr['bet-rejected-remove-icon'] = '';
                dr['cls-strike-through'] = 'strike-through';
                clsStrikeThrough = 'strike-through';
            } else {
                dr['bet-rejected-remove-icon'] = '';
                dr['cls-strike-through'] = '';
                clsStrikeThrough = '';
                _calcTotalWaitingRunning(ostatus);
            };
            var sb = [];
            for (var i = 0; i < bets.length; i++) {
                var bet = bets[i];
                var d = {};
                d['sports'] = bet[0];
                var cls = isOdd ? 'odd' : '';
                d['cls-pending-bets'] = isWaiting ? 'pending-bets' : cls;
                d['TournamentName'] = TiLib.Text.encodeHTML(bet[1]);
                d['homeTeamName'] = bet[2];
                d['awayTeamName'] = bet[3];
                d['mktTypeShortName'] = bet[4];
                d['cls-strike-through'] = clsStrikeThrough;
                d['home-away-team-info'] = _template['home-away-team-info-sec'].getText(d);
                d['betOptionName'] = bet[5];
                d['orderPrice'] = bet[6];
                d['rejecetdStatus'] = '';
                d['stake'] = '';
                d['status'] = '';
                d['order-stake-status-info'] = '';
                d['orderStyle'] = bet[7];
                d['NewBetTypeGroupName'] = bet[8];
                sb.push(_template['order-details-data'].getText(d));
            }
            dr['mktTypeShortName'] = 'MP';
            sb.push(_template['mp-order-stake-status-info'].getText(dr));
            dr['orderDetails'] = sb.join('');
            return _template['bet-row-data'].getText(dr);
        }
    }

    function _getColonTemplate(hdp) {
        while (1) {
            if (hdp.indexOf('##') > -1) {
                var colonTmpl = _template['hdpinfo-colon'].getText();
                hdp = hdp.replace("##", colonTmpl);
            } else {
                break;
            }
        }
        return hdp;
    }

    function _getBetConditionContent(betCondition) {
        var data = betCondition.split(',');
        var sb = [];
        for (var i = 0; i < data.length; i++) {
            sb.push(' <span class="NW">');
            sb.push(data[i]);
            if ((i + 1) == data.length) {
                sb.push('</span>');
            } else {
                sb.push(',</span>');
            }
        }
        var d = {};
        d['betConditionData'] = sb.join('');
        return _template['order-betcondition'].getText(d)
    }

    function _getRunningOrders() {
        var d = {};
        var sb = [];
        var nonLiveRow = 1;
        var rows = 0;
        if (_drawFull) {
            rows = _runningBets.length;
        } else {
            rows = _waitingBets.length > 0 ? 0 : 1;
        }
        for (var i = 0; i < rows; i++) {
            if (_isTransIdIsInRemoved(_runningBets[i][1])) {
                continue;
            }
            if (_syn.noOfCurrRow >= _maxNoOfRows) {
                break;
            }
            var isLiveBet = parseInt(_runningBets[i][3]);
            var isOdd = isLiveBet && isLiveBet == 1 ? false : (nonLiveRow % 2 == 0 ? false : true);
            var rowData = _getOrdersRow(_runningBets[i], false, isOdd);
            if (isLiveBet && isLiveBet == 1) {
                d['pending-bet-row'] = rowData;
                sb.push(_template['pending-bet-data'].getText(d));
            } else {
                nonLiveRow += 1;
                sb.push(rowData);
            }
            _syn.noOfCurrRow += 1;
        }
        return sb.join('');
    }

    function _drawRefreshButtons() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        a = document.getElementById('mb:rf:button');
        if (a) {
            if (_syn.cooldownCount) {
                a.innerHTML = _template['refresh-refreshing'].getText();
            } else if (a.isHover) {
                a.innerHTML = _template['refresh-hover'].getText();
            } else if ((_syn.waitingTotal + _syn.runningTotal) == 0) {
                a.innerHTML = _template['refresh-noauto'].getText();
            } else {
                a.innerHTML = _template['refresh-countdown'].getText({
                    'refresh-count': _syn.blRefreshCounter
                });
            }
        }
    }

    function _calcTotalWaitingRunning(betStatus) {
        switch (betStatus) {
        case _betStatus.waiting:
            _syn.waitingTotal++;
            break;
        case _betStatus.running:
            _syn.runningTotal++;
            break;
        default:
            break;
        }
    }

    function _removeRejectedBets(transID) {
        var rjCookie = CookieHelper.getValue('mini-bl-rj-ids');
        if (!rjCookie) {
            rjCookie = '';
        }
        rjCookie = rjCookie + '~' + transID;
        CookieHelper.setValue('mini-bl-rj-ids', rjCookie, 86400000);
        _draw();
    }

    function _isTransIdIsInRemoved(transID) {
        var rjCookie = CookieHelper.getValue('mini-bl-rj-ids');
        if (rjCookie) {
            if (rjCookie.indexOf('~' + transID) > -1) {
                return true;
            }
            return false;
        } else {
            return false;
        }
    }

    function addCommas(str) {
        var b = str.split(".");
        var n = b[0];
        var a = [];
        while (n.length > 3) {
            var nn = n.substr(n.length - 3);
            a.unshift(nn);
            n = n.substr(0, n.length - 3);
        }
        if (n.length > 0) {
            a.unshift(n);
        }
        n = a.join(',');
        if (b.length == 2)
            n += "." + b[1];
        return n;
    }
}

function __Module_PageHead() {
    var _self = this;
    var _sync = {
        updatingBetCredit: false,
        updatingBetCreditCooldown: 2
    };
    this.initiate = function () {
        TiLib.Timer.addToSecondTimer(_self);
        var creditDisplayCookie = CookieHelper.getValue('ph-credit-display');
        var isCreditShowing = creditDisplayCookie ? (creditDisplayCookie == 1) : true
        _showHideBetCredit(isCreditShowing);
    };
    this.onTime = function () {
        if (_sync.updatingBetCredit && _sync.updatingBetCreditCooldown) {
            _sync.updatingBetCreditCooldown--;
        } else {
            _refreshEnd();
        }
    }
    this.onSettingChanged = function () {
        var names = CookieHelper.getNames('ph-param-');
        if (names) {
            var c = names.length;
            for (var i = 0; i < c; ++i) {
                var value = CookieHelper.getValue(names[i]);
                if (value !== null) {
                    var key = names[i].substring('ph-param-'.length);
                    switch (key) {
                    case 'loginname':
                        if (value != '') {
                            _updateLoginName(value);
                        }
                        break;
                    }
                }
            }
        }
    };
    this.onStatementClick = function () {
        if (TiLib.Browser.isFirefox()) {
            var width = 925;
            TiLib.Window.openWindow('/web-root/restricted/betlist/statement.aspx?isWindow=1', 'Statement', 'scrollbars=yes,resizable=yes,width=' + width + ',height=543');
        } else {
            $M('masking').drawStatement();
        }
    };
    this.onMyBetsClick = function () {
        if (TiLib.Browser.isFirefox()) {
            var width = 925;
            TiLib.Window.openWindow('/web-root/restricted/betlist/running-bet-list.aspx?isWindow=1', 'MyBets', 'scrollbars=yes,resizable=yes,width=' + width + ',height=543');
        } else {
            $M('masking').drawRunningBetList();
        }
    };
    this.onBalanceClick = function () {
        if (TiLib.Browser.isFirefox()) {
            var width = 643;
            TiLib.Window.openWindow('/web-root/restricted/account/balance.aspx?isWindow=1', 'Balance', 'scrollbars=yes,resizable=yes,width=' + width + ',height=543');
        } else {
            $M('masking').drawBalance();
        }
    };
    this.onAcountClick = function () {
        if (TiLib.Browser.isFirefox()) {
            var width = 643;
            TiLib.Window.openWindow('/web-root/restricted/account/profile.aspx?isWindow=1', 'Account', 'scrollbars=yes,resizable=yes,width=' + width + ',height=543');
        } else {
            $M('masking').drawAccount();
        }
    };
    this.onInformLoginNameChange = function (loginNotifyText) {
        var setLoginName = confirm(loginNotifyText);
        if (setLoginName) {
            $M('masking').openSetLoginNamePage();
        }
        return TiLib.Ajax.sendRequest('loginname', '/web-root/restricted/top-module/action-data.aspx?action=loginname');
    };
    this.onUpdateBetCredit = function () {
        if (!_sync.updatingBetCredit) {
            document.getElementById('bet-credit-refresh').className = 'balance-refresh-rotate';
            _sync.updatingBetCredit = true;
            _sync.updatingBetCreditCooldown = 2;
            return TiLib.Ajax.sendRequest('bet-credit', '/web-root/restricted/top-module/action-data.aspx?action=bet-credit');
        }
    };
    this.onUpdateBetCreditCallback = function (amt) {
        var elem = document.getElementById('bet-credit');
        if (elem) {
            elem.innerHTML = amt;
        }
    }
    this.goPaymentSite = function () {
        window.parent.document.location.replace("/web-root/restricted/redirect-page.aspx?p=payment");
    };
    this.goPaymentSitePopup = function () {
        TiLib.Window.openWindow('/web-root/restricted/redirect-page.aspx?p=payment', 'payment', 'scrollbars=yes,width=1008,height=670,status=yes,toolbar=no,menubar=no,location=no');
    };
    this.onShowHideBetCredit = function (isShowing) {
        _showHideBetCredit(isShowing);
    };

    function _showHideBetCredit(isShowing) {
        var creditDiv = document.getElementById('bet-credit-container');
        var iconShow = document.getElementById('icon-show-credit');
        var iconHide = document.getElementById('icon-hide-credit');
        if (creditDiv) {
            if (isShowing) {
                iconShow.className = TiLib.Text.addClassItem(iconShow.className, 'hide');
                iconHide.className = TiLib.Text.removeClassItem(iconHide.className, 'hide');
                creditDiv.className = TiLib.Text.removeClassItem(creditDiv.className, 'hide');
                CookieHelper.setValue('ph-credit-display', 1);
            } else {
                iconHide.className = TiLib.Text.addClassItem(iconHide.className, 'hide');
                iconShow.className = TiLib.Text.removeClassItem(iconShow.className, 'hide');
                creditDiv.className = TiLib.Text.addClassItem(creditDiv.className, 'hide');
                CookieHelper.setValue('ph-credit-display', 0);
            }
        }
    }
    this.onSignOnClick = function () {
        window.parent.document.location.replace("/logout.aspx");
    }

    function _refreshEnd() {
        _sync.updatingBetCredit = false;
        document.getElementById('bet-credit-refresh').className = 'balance-refresh';
    }

    function _updateLoginName(name) {
        var elem = document.getElementById('login-name');
        if (elem) {
            elem.innerHTML = name;
        }
    }
}

function __Module_TopBanner(isNewTVEnabled) {
    var tb_Live_Video_Name = ["sbolivevideo0", "sbolivevideo1", "sbolivevideo2", "sbolivevideo3", "sbolivevideo4"];
    var tb_Live_Video_Ref = [];
    var tb_Live_Video_Count = [-1];
    var _self = this;
    var _sync = {
        dateTimeRefreshRate: 30,
        cooldownCount: 30,
        isFirstLoad: true
    };
    var _state = {
        langSelShowing: false
    };
    this.initiate = function () {
        TiLib.Timer.addToSecondTimer(_self);
        return TiLib.Ajax.sendRequest('datetime', '/web-root/restricted/top-module/action-data.aspx?action=init_anc');
    };
    this.onTime = function () {
        if (_sync.cooldownCount) {
            _sync.cooldownCount--;
        } else {
            _sync.cooldownCount = _sync.dateTimeRefreshRate;
            return TiLib.Ajax.sendRequest('datetime', '/web-root/restricted/top-module/action-data.aspx?action=datetime_anc');
        }
    }
    this.goProduct = function (pcode) {
        var queryParam = TiLib.Url.getQueryParams();
        window.parent.document.location.replace("/web-root/restricted/redirect-page.aspx?at=true&p=" + pcode + "&loginname=" + queryParam['loginname']);
        var event = window.event;
        if (event) {
            if (event.stopPropagation) {
                event.stopPropagation();
            } else {
                event.cancelBubble = true;
            }
        }
    };

    function _getRoyalCasinoPopupSize() {
        var userAgent = navigator.userAgent.toLowerCase();
        var widthSize = window.screen.width;
        var heightSize = window.screen.height;
        var newW;
        var newH;
        var arr = [];
        arr.push('resizable=1');
        if (widthSize / heightSize > 1.5) {
            newW = widthSize * 0.82;
            newH = heightSize * 0.82;
        } else {
            newW = widthSize * 0.95;
            newH = heightSize * 0.95;
        }
        if (newW / newH > 16 / 9) {
            newW = newH * (16 / 9);
        } else {
            newH = newW * (9 / 16);
        }
        if (userAgent.indexOf('applewebkit') > -1 && userAgent.indexOf('chrome') < 0) newH -= 60;
        arr.push(',width=');
        arr.push(newW);
        arr.push(',height=');
        arr.push(newH);
        return arr.join('');
    }
    this.openRoyalCasino = function () {
        TiLib.Window.openWindow('/web-root/restricted/redirect-page.aspx?p=rc', 'RoyalCasino', _getRoyalCasinoPopupSize());
    }
    this.onUpdateTime = function (t) {
        var elem = document.getElementById('top-banner-time');
        if (elem) {
            elem.innerHTML = t;
        }
        if ($M('slider-bar') && $M('slider-bar').onUpdateTime) {
            $M('slider-bar').onUpdateTime(t);
        }
    }
    this.onSBOBETvClick = function (eid, position) {
        tb_Live_Video_Count[0]++;
        for (var i = 0; i < 5; ++i) {
            if (_windowAvailable(i)) {
                var url = '/web-root/restricted/video/video-page.aspx?event=' + ((eid == undefined) ? 0 : eid);
                tb_Live_Video_Ref[i] = _openLiveTV(url, tb_Live_Video_Name[i]);
                break;
            }
        }
        if (i == 5) {
            i = tb_Live_Video_Count[0] % 5;
            tb_Live_Video_Ref[i] = _openLiveTV('', tb_Live_Video_Name[i]);
        }
        if (!position) position = 'top'
        if ($M('global') && $M('global').incGA) {
            $M('global').incGA('sbobetv', position);
        }
    };

    function _windowAvailable(index) {
        if (tb_Live_Video_Ref != undefined && tb_Live_Video_Ref[index] && tb_Live_Video_Ref[index].open && !tb_Live_Video_Ref[index].closed) {
            return false;
        }
        if (TiLib.Window.getWindow(tb_Live_Video_Name[index])) {
            return false;
        }
        return true;
    }

    function _openLiveTV(url, name) {
        var userAgent = navigator.userAgent.toLowerCase();
        var w, h;
        if (userAgent.indexOf("firefox") > -1) {
            w = 414 + 371;
            h = 373;
        } else if (userAgent.indexOf("msie") > -1) {
            if (userAgent.indexOf("msie 6.0") > -1) {
                w = 413 + 371;
                h = 373;
            } else {
                w = 414 + 371;
                h = 372;
            }
        } else if (userAgent.indexOf("chrome") > -1) {
            w = 415 + 371;
            h = 377;
        } else if (userAgent.indexOf("applewebkit") > -1) {
            w = 414 + 371;
            h = 375;
        } else {
            w = 414 + 371;
            h = 375;
        }
        var attributes = 'scrollbars=no,width=' + w + ',height=' + h;
        return TiLib.Window.openWindow(url, name, attributes);
    }
    this.onResultClick = function () {
        TiLib.Window.openWindow('/web-root/restricted/result/results-more.aspx', 'result', 'scrollbars=yes,resizable=0,width=780,height=670');
        return true;
    };
    this.onTvScheduleClick = function () {
        var sport = _getDisplaySetting('sport');
        var url = '/web-root/restricted/top-module/tv.aspx';
        var ourl = '/web-root/restricted/top-module/otv.aspx';
        if (isNewTVEnabled === 1) {
            if (sport) {
                url += '?sport=' + sport;
            }
        } else {
            if (sport) {
                ourl += '?sport=' + sport;
            }
        }
        var specs = 'scrollbars=yes,resizable=0,width=670,height=600,left=660,top=200';
        var ospecs = 'scrollbars=yes,resizable=0,width=631,height=600,left=660,top=200';
        var browserInfo = TiLib.Browser.getBrowserInfo();
        if (browserInfo.name == 'Internet Explorer' && browserInfo.version == '9') {
            specs = 'scrollbars=yes,resizable=0,width=670,height=600,left=660,top=200';
        }
        if (isNewTVEnabled === 1) {
            TiLib.Window.openWindow(url, 'tvschedule', specs);
        } else {
            TiLib.Window.openWindow(ourl, 'tvschedule', ospecs);
        }
        return true;
    };

    function _getDisplaySetting(key) {
        if ($M('odds-display') && $M('odds-display').getDisplaySetting) {
            return $M('odds-display').getDisplaySetting(key);
        }
        if ($M('live-sport-display') && $M('live-sport-display').getDisplaySetting) {
            return $M('live-sport-display').getDisplaySetting(key);
        }
    }
    this.onLanguageClick = function () {
        _showHideLanguageSelection();
    };

    function _showHideLanguageSelection() {
        var div = document.getElementById('lang-menu');
        if (!div) {
            return false;
        }
        if (_state.langSelShowing) {
            div.className = TiLib.Text.addClassItem(div.className, 'hide');
        } else {
            div.className = TiLib.Text.removeClassItem(div.className, 'hide');
            TiLib.Event.addListener('mousedown', _onMouseDown);
        }
        _state.langSelShowing = !_state.langSelShowing;
    };

    function _hideLanguageSelection() {
        var div = document.getElementById('lang-menu');
        if (!div) {
            return false;
        }
        div.className = TiLib.Text.addClassItem(div.className, 'hide');
        _state.langSelShowing = false;
    }

    function _onMouseDown(event) {
        var e = event;
        var target = (e.target || e.srcElement);
        var node = target.parentNode;
        var isWithinArea = false;
        while (node) {
            if (node.id == 'lang-menu' || node.id == 'selected-lang') {
                isWithinArea = true;
                return true;
            }
            node = node.parentNode;
        }
        if (!isWithinArea) {
            _hideLanguageSelection();
            TiLib.Event.removeListener('mousedown', _onMouseDown);
        }
        true;
    }
}

function __Module_Announcement() {
    var _TemplateName = 'top-module/announcement';
    var _template = null;
    var _data;
    var _unreadCount;
    var _IsShowingAccouncement = false;
    var _sync = {
        waitingTemplate: false,
        waitingCounterTemplate: false
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_template) {
                    if (_sync.waitingTemplate) {
                        _sync.waitingTemplate = false;
                        _draw();
                    }
                    if (_sync.waitingCounterTemplate) {
                        _sync.waitingCounterTemplate = false;
                        _showHideAnnouncementCount(_unreadCount);
                    }
                }
            }
        }
    };
    this.onUpdate = function (data) {
        if (!data) {
            return;
        }
        _data = data;
        _draw();
    };

    function _draw() {
        if (!_template) {
            _sync.waitingTemplate = true;
            return;
        }
        var data = _data;
        var dc = data.length;
        var d = {};
        var sb = [];
        var hasTop = false;
        for (var i = 0; i < dc; i++) {
            d = {};
            var msg = data[i];
            if (i == 0) {
                d['first-msg-class'] = 'BTN';
            }
            d['is-ontop-class'] = '';
            if (msg[2] == 1) {
                hasTop = true;
                d['is-ontop-class'] = 'announcement-top-msg';
            }
            d['msg-id'] = msg[0];
            d['msg-post-date'] = msg[1];
            d['msg-content'] = msg[3];
            var tmpl = _template['message-div'].getText(d);
            sb.push(tmpl);
        }
        d['top-class'] = hasTop ? 'announcement-arrow-top-msg' : '';
        d['message'] = sb.join('');
        document.getElementById('announcement-div').innerHTML = _template['main-div'].getText(d);
        _IsShowingAccouncement = !_IsShowingAccouncement;
        _showHideAnnouncementCount('');
        ScrollDiv.draw('ann-scroll-area', 200);
        TiLib.Event.addListener('mousedown', _onMouseDown);
    }
    this.onViewFullClick = function () {
        TiLib.Window.openWindow('/web-root/restricted/top-module/announcement.aspx', 'announcement', 'scrollbars=yes,resizable=no,width=630,height=600');
        _hideAnnouncementDiv();
    }
    this.onUpdateUnreadCount = function (unreadCount) {
        _showHideAnnouncementCount(unreadCount);
    }

    function _showHideAnnouncementCount(unreadCount) {
        if (unreadCount == undefined) {
            return;
        }
        _unreadCount = unreadCount;
        if (!_template) {
            _sync.waitingCounterTemplate = true;
            return;
        }
        var elem = document.getElementById('anm-count');
        if (elem) {
            if (unreadCount == '') {
                elem.innerHTML = '';
            } else {
                var d = {};
                d['count'] = unreadCount;
                elem.innerHTML = _template['message-count'].getText(d);
            }
        }
    }
    this.onAnnouncementClick = function () {
        if (_IsShowingAccouncement) {
            _hideAnnouncementDiv();
        } else {
            return TiLib.Ajax.sendRequest('announcement', '/web-root/restricted/top-module/announcement-data.aspx');
        }
    }

    function _hideAnnouncementDiv() {
        var elem = document.getElementById('announcement-div');
        if (elem) {
            elem.innerHTML = '';
        }
        _IsShowingAccouncement = !_IsShowingAccouncement;
    }

    function _onMouseDown(event) {
        var e = event;
        var target = (e.target || e.srcElement);
        var node = target.parentNode;
        var isWithinArea = false;
        while (node) {
            if (node.id == 'ann-area-div' || node.id == 'ann-link-area') {
                isWithinArea = true;
                break;
            }
            node = node.parentNode;
        }
        if (!isWithinArea) {
            _hideAnnouncementDiv();
            TiLib.Event.removeListener('mousedown', _onMouseDown);
        }
        true;
    }
}

function __Module_OddsDisplaySetting(isSoundMuted) {
    var _IsSoundMuted = isSoundMuted;
    var _TemplateName = 'top-module/odds-display-setting';
    var _template = null;
    var _data;
    var _OddsDisplaySettingElements = ['price-style', 'odds-mode', 'sorting', 'market-showing', 'daylight-type'];
    var _PeriodElemetes = ['before', 'after', 'all'];
    var _MainMarketSelection_config = {
        1: true,
        3: true,
        4: true,
        7: true
    };
    var _OddsMode_config = {
        1: true,
        2: true,
        3: true,
        13: true
    };
    var _PriceStyle_config = {
        1: true,
        2: true,
        3: true,
        4: true,
        7: true,
        12: true,
        13: true
    };
    var _sync = {
        waitingTemplate: false
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        _draw();
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_sync.waitingTemplate && _template) {
                    _sync.waitingTemplate = false;
                    _draw();
                }
            }
        }
    };
    this.onSettingChanged = function () {
        _draw();
    };
    this.onSoundClick = function () {
        var sb = [];
        sb.push('/web-root/restricted/top-module/action-data.aspx?action=sound');
        return TiLib.Ajax.sendRequest('od-setting', sb.join(''));
    };
    this.onSoundCallback = function (isMute) {
        _IsSoundMuted = isMute;
        _draw();
    };
    this.onPlaySound = function (soundFile) {
        if (soundFile != '' && soundFile != 'none') {
            var fullPath = '/images/goal-sound/' + soundFile;
            var div = document.getElementById('div-sound');
            if (!div) {
                div = document.createElement('div');
                div.setAttribute('id', 'div-sound');
                div.className = 'hide';
                document.body.appendChild(div);
            }
            div.innerHTML = '<embed width="1" height="1" src="' + fullPath + '.swf"/>';
        }
    };
    this.setDisplaySetting = function (key, val, position) {
        if ($M('odds-display') && $M('odds-display').setDisplaySetting) {
            $M('odds-display').setDisplaySetting(key, val, position);
        }
        if ($M('live-sport-display') && $M('live-sport-display').setDisplaySetting) {
            $M('live-sport-display').setDisplaySetting(key, val, position);
        }
        _draw();
    };
    this.draw = function () {
        _draw();
    };

    function _draw() {
        if (!_template) {
            _sync.waitingTemplate = true;
            return;
        }
        var odSettingElements = _OddsDisplaySettingElements;
        var sb = [];
        var d = {};
        var sbSlider = [];
        d['sound-class'] = (_IsSoundMuted == 1) ? 'sound-off-icon' : 'sound-on-icon';
        d['sound-title'] = (_IsSoundMuted == 1) ? _template['turn-on-sound'].getText({}) : _template['turn-off-sound'].getText({});
        sb.push(_template['static-icon'].getText(d));
        for (var i = 0; i < odSettingElements.length; i++) {
            var key = odSettingElements[i];
            var val = _getDisplaySetting(key);
            var marketPage = _getDisplaySetting('market-page');
            if (val != null && val != undefined) {
                if (key == 'price-style' && val == 3) {
                    continue;
                }
                if (key == 'daylight-type') {
                    var daylightType = val;
                    var sportId = _getDisplaySetting('sport');
                    var daylightTypePeriod = _getDisplaySetting('daylight-type-period');
                    if (daylightType != 0 && daylightTypePeriod != null && marketPage == 1 && sportId == 1) {
                        d['before'] = _template['before-' + daylightTypePeriod].getText();
                        d['after'] = _template['after-' + daylightTypePeriod].getText();
                        d['all'] = _template['all-time'].getText();
                        d['daylight-selected'] = daylightType == 1 ? d['before'] : (daylightType == 2 ? d['after'] : d['all']);
                        var tmpl = _template[key + '-ddl'];
                        sb.push(tmpl.getText(d));
                        var tmplSlider = _template['slider-bar-' + key + '-ddl'];
                        sbSlider.push(tmplSlider.getText(d));
                    }
                    continue;
                }
                if (key == 'market-showing' && marketPage == 13) {
                    continue;
                }
                d['value'] = _isIconOff(key) ? (val + '-off global-icon-off') : val;
                d['title'] = _isIconOff(key) ? _template['off-icon-title'].getText({}) : '';
                var tmpl = _template[key + '-ddl'];
                sb.push(tmpl.getText(d));
                var tmplSlider = _template['slider-bar-' + key + '-ddl'];
                sbSlider.push(tmplSlider.getText(d));
            }
        }
        d['odds-display-setting-icons'] = sbSlider.reverse().join('');
        var elem = document.getElementById('odds-display-setting');
        if (elem) {
            elem.innerHTML = sb.join('');
        }
        elem = document.getElementById('slider-bar-od-setting-icons');
        if (elem) {
            elem.innerHTML = _template['slider-bar-static-icon'].getText(d);
        }
    }

    function _isIconOff(key) {
        var currMktPage = _getDisplaySetting('market-page');
        if (key == 'price-style') {
            var psConfig = _PriceStyle_config[currMktPage];
            if (!psConfig) {
                return true;
            }
        }
        if (key == 'odds-mode') {
            var omConfig = _OddsMode_config[currMktPage];
            if (!omConfig) {
                return true;
            }
        }
        if (key == 'market-showing') {
            var mktConfig = _MainMarketSelection_config[currMktPage];
            if (!mktConfig) {
                return true
            }
        }
        if (key == 'sorting') {
            if (currMktPage == 10 || currMktPage == 12) {
                return true;
            }
        }
        return false;
    }

    function _getDisplaySetting(key) {
        if ($M('odds-display') && $M('odds-display').getDisplaySetting) {
            return $M('odds-display').getDisplaySetting(key);
        }
        if ($M('live-sport-display') && $M('live-sport-display').getDisplaySetting) {
            return $M('live-sport-display').getDisplaySetting(key);
        }
    }
}

function __Module_SliderBar() {
    var _self = this;
    var _TemplateName = 'top-module/slider-bar/slider-bar-client';
    var _template = null;
    var _cache = null;
    var _sync = {
        waitingTemplate: false,
        waitingData: false,
        isSliderBarShowing: false
    };
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
        TiLib.Event.addListener('scroll', _OnScroll);
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_sync.waitingTemplate && _template) {
                    _sync.waitingTemplate = false;
                    _draw();
                }
            }
        }
    };
    this.onUpdate = function () {
        if ($M('sport-market') && $M('sport-market').getCache) {
            _cache = $M('sport-market').getCache();
            _sync.waitingData = false;
            _draw();
        }
    };
    this.onClick = function (event) {
        if (!event) event = window.event;
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    };

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'sd') {
                switch (atom[2]) {
                case 'sport':
                    if (count >= 4) {
                        var sliderSport = document.getElementById('slider-sports');
                        _self.hideSubMenu(sliderSport, 'sb-sports-menu');
                        $M('sport-market').switchSport(atom[3]);
                    }
                    return false;
                case 'market':
                    if (count >= 4) {
                        var sliderMarket = document.getElementById('slider-markets');
                        _self.hideSubMenu(sliderMarket, 'sb-market-menu');
                        $M('sport-market').switchMarket(parseInt(atom[3]));
                    }
                    return false;
                }
            }
        }
        return true;
    }
    this.onUpdateTime = function (t) {
        var elem = document.getElementById('slider-bar-time');
        if (elem) {
            elem.innerHTML = t + ' GMT+8';
        }
    };

    function _isQuirkMode() {
        var version = TiLib.Browser.getVersion();
        var hasDoctype = document.compatMode != 'BackCompat';
        return !hasDoctype && TiLib.Browser.isInternetExplorer() && (version == 8 || version == 9 || version == 7);
    }

    function _OnScroll(params) {
        if (params && params.y != undefined) {
            var elem = document.getElementById('slider-bar');
            if (elem) {
                if (params.y >= 45 && !_sync.isSliderBarShowing) {
                    if (_isQuirkMode()) {
                        elem.className = TiLib.Text.addClassItem(elem.className, 'fixed-slider-bar');
                        TiLib.UI.addMoveVerticalEffect('slider-bar', -180, -98, 500);
                    } else {
                        elem.style.top = '30px';
                        TiLib.UI.addMoveVerticalEffect('slider-bar', -100, 30, 500);
                    }
                    _sync.isSliderBarShowing = true;
                }
                if (params.y < 45 && _sync.isSliderBarShowing) {
                    if (_isQuirkMode()) {
                        TiLib.UI.addMoveVerticalEffect('slider-bar', -98, -180, 500);
                    } else {
                        elem.style.top = '-100px';
                        TiLib.UI.addMoveVerticalEffect('slider-bar', 24, -100, 500);
                    }
                    _sync.isSliderBarShowing = false;
                }
            }
        }
    }

    function _updateOddsDisplaySetting() {
        if ($M('odds-display-setting') && $M('odds-display-setting').draw) {
            $M('odds-display-setting').draw();
        }
    }
    this.showSubMenu = function (curElem, elemId) {
        if (curElem) {
            curElem.className = TiLib.Text.addClassItem(curElem.className, 'toolbar-selection-hover');
        }
        var elem = document.getElementById(elemId);
        if (elem) {
            elem.className = TiLib.Text.removeClassItem(elem.className, 'hide');
        }
    };
    this.hideSubMenu = function (curElem, elemId) {
        var elem = document.getElementById(elemId);
        if (elem) {
            elem.className = TiLib.Text.addClassItem(elem.className, 'hide');
        }
        if (curElem) {
            curElem.className = TiLib.Text.removeClassItem(curElem.className, 'toolbar-selection-hover');
        }
    };
    this.draw = function () {
        _draw();
    };

    function _draw(isShowing) {
        if (!_template) {
            _sync.waitingTemplate = true;
            return;
        }
        if (!_cache) {
            _sync.waitingData = true;
            return;
        }
        var sliderDiv = document.getElementById('slider-sports');
        if (sliderDiv === null || sliderDiv === undefined) {
            return;
        }
        var cache = _cache;
        var d = {};
        var selectedSportId = $M('odds-display').getDisplaySetting('sport');
        var sportArray = cache.getSportArray();
        var c = sportArray.length;
        var sportItems = [];
        var hasSport = false;
        d['elem-id'] = 'sports-menu';
        for (var i = 0; i < c; ++i) {
            var sport = sportArray[i];
            var sportId = sport[0];
            var sportName = cache.getSportName(sportId);
            var sportEventCount = sport[2];
            if (sportEventCount <= 0) continue;
            if (selectedSportId == sportId) {
                d['selected-element-name'] = sportName;
            }
            hasSport = true;
            hasLive = false;
            var marketPageCount = cache.getSportMarketPageCount(sportId);
            if (marketPageCount) {
                for (var j = 0; j < marketPageCount.length; j++) {
                    if (marketPageCount[j][1] > 0 && marketPageCount[j][2] == 1) {
                        hasLive = true;
                        break;
                    }
                }
            }
            d['counter-div'] = _template['counter-div'].getText({
                'count': sportEventCount
            });
            d['live'] = hasLive ? 'live' : '';
            d['hide-class'] = isShowing ? '' : 'hide';
            d['sport-id'] = sportId;
            d['sport-name'] = sportName;
            sportItems.push(_template['sports-li-event'].getText(d));
        }
        if (sportItems.length == 0) {
            var sport = sportArray[0];
            var sportId = sport[0];
            var sportName = cache.getSportName(sportId);
            var sportEventCount = sport[2];
            d['counter-div'] = _template['counter-div'].getText({
                'count': 0
            });
            d['selected-element-name'] = sportName;
            d['sport-id'] = sportId;
            d['sport-name'] = sportName;
            sportItems.push(_template['sports-li-event'].getText(d));
        }
        d['elements'] = sportItems.join('');
        sliderDiv.innerHTML = _template['container-div'].getText(d);
        d = {};
        var selectedMarketPageId = $M('odds-display').getDisplaySetting('market-page');
        var marketPageCountArray = cache.getSportMarketPageCount(selectedSportId);
        c = marketPageCountArray.length;
        var marketPageItems = [];
        var totalParlayCount = cache.getTotalParlayCount();
        d['elem-id'] = 'market-menu';
        for (var i = 0; i < c; ++i) {
            var marketPageCount = marketPageCountArray[i];
            var marketPageId = marketPageCount[0];
            var marketPageEventCount = marketPageCount[1];
            var marketPage = cache.getMarketPage(marketPageId);
            var marketPageName = cache.getMarketPageName(marketPageId);
            if (marketPageId == 3 && marketPageEventCount == 0) {
                continue;
            }
            d['counter-div'] = _template['counter-div'].getText({
                'count': marketPageEventCount
            });
            if (selectedMarketPageId == marketPageId) {
                d['selected-element-name'] = marketPageName;
            }
            d['live'] = (marketPageCount[2] > 0 && marketPageEventCount > 0) ? 'live' : '';
            d['hide-class'] = isShowing ? '' : 'hide';
            d['market-id'] = marketPageId;
            d['market-name'] = marketPageName;
            marketPageItems.push(_template['markets-li-event'].getText(d));
        }
        d['elements'] = marketPageItems.join('');
        document.getElementById('slider-markets').innerHTML = _template['container-div'].getText(d);
    }
}

function __Module_Masking(accSetting) {
    var _TemplateName = 'top-module/masking';
    var _template = null;
    var _sync = {
        waitingTemplate: false,
        action: ''
    };
    var _accSetting = accSetting;
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
    };
    this.onTemplate = function (name) {
        if (name == _TemplateName) {
            var templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_sync.waitingTemplate && _template) {
                    _sync.waitingTemplate = false;
                    _draw();
                }
            }
        }
    };
    this.onChangeBetlistProd = function (elem) {
        var iframe = document.getElementById('running-bet-list-iframe');
        if (elem && elem.value != '' && iframe) {
            iframe.src = '/web-root/restricted/betlist/running-bet-list.aspx?p=' + elem.value;
        }
    }
    this.onClose = function () {
        _onClose();
    };
    this.drawRunningBetList = function () {
        _drawRunningBetList();
    };
    this.drawBalance = function () {
        _drawAccount(true);
    };
    this.drawAccount = function () {
        _drawAccount(false);
    };
    this.drawStatement = function () {
        _drawStatement();
    };
    this.drawResult = function () {
        _drawResult();
    };
    this.openSetLoginNamePage = function () {
        _drawLoginNamePage();
    }
    this.openWindow = function (page) {
        if (page) {
            _openWindow(page);
        }
    }

    function _draw() {
        if (_sync.action != '') {
            switch (_sync.action) {
            case 'running-bet-list':
                _drawRunningBetList();
                break;
            case 'balance':
                _drawAccount(true);
                break;
            case 'account':
                _drawAccount(false);
                break;
            case 'statement':
                _drawStatement();
                break;
            case 'result':
                _drawStatement();
                break;
            case 'loginname':
                _drawLoginNamePage();
                break;
            }
        }
    }

    function _drawRunningBetList() {
        if (!_template) {
            _sync.action = 'running-bet-list';
            _sync.waitingTemplate = true;
            return;
        }
        _sync.action = '';
        var sb = [];
        var d = {};
        d['product-selection'] = _getProductSelectionList();
        elem = document.getElementById('div-popup');
        if (elem) {
            elem.className = TiLib.Text.removeClassItem(elem.className, 'hide');
            elem.innerHTML = _template['running-betlist-div'].getText(d);
            _onPostDraw();
        }
    }

    function _getProductSelectionList() {
        var sb = [];
        if (_accSetting) {
            if (_accSetting.isLcEnabled) {
                sb.push(_template['live-casino'].getText({}));
            }
            if (_accSetting.isRtEnabled) {
                sb.push(_template['race-tote'].getText({}));
            }
            if (_accSetting.isGmEnabled) {
                sb.push(_template['games'].getText({}));
            }
        }
        return sb.join('');
    }

    function _drawAccount(isBalancePage) {
        if (!_template) {
            _sync.action = isBalancePage ? 'balance' : 'account';
            _sync.waitingTemplate = true;
            return;
        }
        _sync.action = '';
        var sb = [];
        var d = {};
        d['src-url'] = isBalancePage ? _template['balance-url'].getText({}) : _template['account-url'].getText({});
        elem = document.getElementById('div-popup');
        if (elem) {
            elem.className = TiLib.Text.removeClassItem(elem.className, 'hide');
            elem.innerHTML = _template['account-container'].getText(d);
            _onPostDraw();
        }
    }

    function _drawStatement() {
        if (!_template) {
            _sync.action = 'statement';
            _sync.waitingTemplate = true;
            return;
        }
        _sync.action = '';
        elem = document.getElementById('div-popup');
        if (elem) {
            elem.className = TiLib.Text.removeClassItem(elem.className, 'hide');
            elem.innerHTML = _template['statement-div'].getText({});
            _onPostDraw();
        }
    }

    function _drawResult() {
        if (!_template) {
            _sync.action = 'result';
            _sync.waitingTemplate = true;
            return;
        }
        _sync.action = '';
        elem = document.getElementById('div-popup');
        if (elem) {
            elem.className = TiLib.Text.removeClassItem(elem.className, 'hide');
            elem.innerHTML = _template['result-div'].getText({});
            _onPostDraw();
        }
    }

    function _drawLoginNamePage() {
        if (!_template) {
            _sync.action = 'loginname';
            _sync.waitingTemplate = true;
            return;
        }
        _sync.action = '';
        var sb = [];
        var d = {};
        d['src-url'] = _template['loginname-url'].getText({});
        elem = document.getElementById('div-popup');
        if (elem) {
            elem.className = TiLib.Text.removeClassItem(elem.className, 'hide');
            elem.innerHTML = _template['account-container'].getText(d);
            _onPostDraw();
        }
    }

    function _onPostDraw() {
        var viewPort = TiLib.Event.getViewPortSize();
        var adjustTop = 0;
        if (viewPort && viewPort.height && viewPort.height < 550) {
            adjustTop = 60;
        }
        if ($M('global') && $M('global').disablePageScroll) {
            $M('global').disablePageScroll();
        }
        var div = document.getElementById('div-popup');
        if (div) {
            var topPosition = TiLib.Document.getScrollHeight() + (TiLib.Document.getInnerHeight() / 2);
            var leftPosition = TiLib.Document.getScrollWidth() + (TiLib.Document.getInnerWidth() / 2);
            div.style.position = 'absolute';
            div.style.top = (topPosition + adjustTop) + 'px';
            div.style.left = leftPosition + 'px';
            div.style.zIndex = 9999;
            var mask = document.getElementById('popup-mask');
            if (mask) {
                mask.className = 'popup-mask';
            }
        }
        TiLib.Event.addListener('keydown', _onKeyDown);
        TiLib.Event.addListener('mousedown', _onMouseDown);
    }

    function _onKeyDown(event) {
        if (event.keyCode == 27) {
            _onClose();
        }
    }

    function _onClose() {
        var div = document.getElementById('div-popup');
        if (div) {
            div.innerHTML = '';
            div.className = TiLib.Text.addClassItem(div.className, 'hide');
        }
        if ($M('global') && $M('global').enablePageScroll) {
            $M('global').enablePageScroll();
        }
        var mask = document.getElementById('popup-mask');
        if (mask) {
            mask.className = '';
        }
        TiLib.Event.removeListener('mousedown', _onMouseDown);
        TiLib.Event.removeListener('keydown', _onKeyDown);
    }

    function _onMouseDown(event) {
        var e = event;
        var node = (e.target || e.srcElement);
        var isWithinArea = true;
        while (node) {
            if (node.id == 'popup-mask') {
                isWithinArea = false;
                break;
            }
            node = node.parentNode;
        }
        if (!isWithinArea) {
            _onClose();
        }
        true;
    }

    function _openWindow(page) {
        if (page) {
            var iframe = null;
            var width = 925;
            switch (page) {
            case 'running-bet':
                iframe = document.getElementById('running-bet-list-iframe');
                break;
            case 'statement':
                iframe = document.getElementById('statement-iframe');
                break;
            case 'account':
                width = 643;
                iframe = document.getElementById('account-iframe');
                break;
            }
            if (iframe) {
                var doc = iframe.contentWindow || iframe.contentDocument;
                if (doc) {
                    var href = doc.location.href;
                    var params = TiLib.Url.getQueryParams(doc);
                    params['isWindow'] = 1;
                    var paramsString = TiLib.Url.buildQueryString(params);
                    TiLib.Window.openWindow(href.split('?')[0] + '?' + paramsString, page, 'scrollbars=yes,resizable=yes,width=' + width + ',height=543');
                    _onClose();
                }
            }
        }
    }
}

function __Module_Right_Column(lang) {
    var _TemplateName = 'right-column/right-column';
    var _GamesTemplateName = 'right-column/games-content';
    var _promoFlashLang = lang;
    var _elementDic = {};
    var _self = this;
    var _template = null;
    var _gamesTemplate = null;
    var _selectedTab = 'sports';
    var _supportedTabs = ['sports', 'games'];
    var _syn = {
        waitingTemplate: true,
        waitingGamesTemplate: true,
        gamesTabName: _supportedTabs[1]
    }
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
    };
    this.getSelecetdTab = function () {
        return _selectedTab;
    }
    this.hasInterestedEvent = function (hasEvent) {
        _showHidePromotionalContent(!hasEvent);
    }
    this.onTemplate = function (name) {
        var templateText;
        if (name == _TemplateName) {
            templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_syn.waitingTemplate) {
                    if (_template) {
                        _syn.waitingTemplate = false;
                        _draw();
                        _drawPromotionalContent();
                    }
                }
            }
        } else if (name == _GamesTemplateName) {
            templateText = $P.getTemplate(_GamesTemplateName);
            if (templateText) {
                _gamesTemplate = TiLib.Template.createTemplates(templateText);
                if (_syn.waitingGamesTemplate) {
                    if (_gamesTemplate) {
                        _syn.waitingGamesTemplate = false;
                        _drawGamesContent();
                    }
                }
            }
        }
    };
    this.onClick = function (event) {
        if (!event) event = window.event;
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    };

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'rc') {
                switch (atom[2]) {
                case 'tab':
                    if (count >= 4) {
                        _switchToTab(atom[3]);
                    }
                    return false;
                }
            }
        }
        return true;
    }

    function _switchToTab(tabName) {
        if (!$M('right-col-mini-game').isMiniGameTabEnabled()) {
            return;
        }
        if (_supportedTabs.contains(tabName) >= 0) {
            _selectedTab = tabName;
            _draw();
            if (tabName == _syn.gamesTabName) {
                if (!_gamesTemplate) {
                    var templateText = $P.getTemplate(_GamesTemplateName);
                    if (templateText) {
                        _gamesTemplate = TiLib.Template.createTemplates(templateText);
                    }
                }
                if (!$M('right-col-mini-game').isGameRunningNow()) {
                    _drawGamesContent();
                }
            }
        }
    }

    function _getElement(elementName) {
        if (!_elementDic[elementName]) {
            _elementDic[elementName] = document.getElementById(elementName);
        }
        return _elementDic[elementName];
    }

    function _draw() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var d = {};
        var selections = [];
        d['total-tabs'] = _supportedTabs.length;
        for (var i = 0; i < _supportedTabs.length; i++) {
            d['selection-code'] = _supportedTabs[i];
            d['position'] = i == 0 ? 'first' : 'next';
            d['selected'] = (_supportedTabs[i] == _selectedTab) ? 'selected' : '';
            d['selection-label'] = _template[_supportedTabs[i] + '-label'].getText(d);
            selections.push(_template['top-selection'].getText(d));
        }
        d['selections'] = selections.join('');
        var rightColumnTab = _getElement('right-column-tab');
        if (rightColumnTab) {
            rightColumnTab.innerHTML = _template['top-bar'].getText(d);
        }
        for (var i = 0; i < _supportedTabs.length; i++) {
            var body = _getElement('right-' + _supportedTabs[i] + '-body');
            if (body) {
                if (_supportedTabs[i] == _selectedTab) {
                    body.className = TiLib.Text.removeClassItem(body.className, 'hide');
                    if (TiLib.Browser.isFirefox() && (_supportedTabs[i] == _syn.gamesTabName)) {
                        body.className = 'right-games-body';
                    }
                } else {
                    body.className = TiLib.Text.addClassItem(body.className, 'hide');
                    if (TiLib.Browser.isFirefox() && (_supportedTabs[i] == _syn.gamesTabName)) {
                        body.className = 'Vhide';
                    }
                }
            }
        }
        if (!$M('right-col-mini-game').isMiniGameTabEnabled()) {
            var div = _getElement('bu:rc:tab:games');
            if (div) {
                div.style.display = 'none';
                var spDiv = _getElement('bu:rc:tab:sports');
                if (spDiv) {
                    spDiv.className = 'r-column-tab-first selected';
                }
            }
        }
        if (_selectedTab == 'sports' && $M('interested-event') && $M('interested-event').draw) {
            $M('interested-event').draw();
        }
    }

    function _drawGamesContent() {
        if (!_gamesTemplate) {
            _syn.waitingGamesTemplate = true;
            return;
        }
        var gamesBody = _getElement('right-games-body');
        if (gamesBody) {
            gamesBody.innerHTML = $M('right-col-mini-game').getContent();
        }
    }

    function _drawPromotionalContent() {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        var promotionalContent = _getElement('promotional-content');
        if (promotionalContent) {
            var d = {};
            d['lang'] = _promoFlashLang == 'en' ? '' : '_' + _promoFlashLang;
            if (TiLib.Browser.hasFlash()) {
                promotionalContent.innerHTML = _template['promotional-content-swf'].getText(d);
            } else {
                promotionalContent.innerHTML = _template['promotional-content-img'].getText(d);
            }
        }
    }

    function _showHidePromotionalContent(isShowing) {
        var promotionalContent = _getElement('promotional-content');
        if (promotionalContent) {
            if (isShowing) {
                promotionalContent.className = TiLib.Text.removeClassItem(promotionalContent.className, 'hide');
            } else {
                promotionalContent.className = TiLib.Text.addClassItem(promotionalContent.className, 'hide');
            }
        }
    }
}

function __Module_Mini_Game(isTabEnabled, gameList) {
    var _TemplateName = 'right-column/games-content';
    var _gamesSSOURL = '/web-root/restricted/mini-game/sso-mini-games.aspx?';
    var _gamesGetDataURL = '/web-root/restricted/mini-game/mini-games-data.aspx?';
    var _self = this;
    var _template = null;
    var _isTabEnabled = parseInt(isTabEnabled, 10);
    var _syn = {
        waitingTemplate: true,
        serverError: 0,
        disableError: 0,
        listModeDisp: 'list',
        playModeDisp: 'play',
        selectedGameId: 0,
        isGameRunning: 0,
        tabName: 'games'
    }
    var _gameList = gameList;
    this.initiate = function () {
        var templateText = $P.getTemplate(_TemplateName);
        if (templateText) {
            _template = TiLib.Template.createTemplates(templateText);
        }
    };
    this.onTemplate = function (name) {
        var templateText;
        if (name == _TemplateName) {
            templateText = $P.getTemplate(_TemplateName);
            if (templateText) {
                _template = TiLib.Template.createTemplates(templateText);
                if (_syn.waitingTemplate) {
                    if (_template) {
                        _syn.waitingTemplate = false;
                        _draw();
                    }
                }
            }
        }
    };
    this.onUpdate = function (data) {
        if ($M('right-column').getSelecetdTab() != _syn.tabName) {
            return;
        }
        _gameList = data;
        _drawGamesContent();
    }
    this.isMiniGameTabEnabled = function () {
        return _isTabEnabled == 1 ? true : false;
    }
    this.getContent = function (mode) {
        _submit(_gamesGetDataURL);
    }
    this.onServerError = function (gid) {
        _syn.selectedGameId = gid;
        _syn.serverError = 1;
        _drawGamesContent();
        _syn.serverError = 0;
    }
    this.onDisableError = function (gid) {
        _syn.selectedGameId = gid;
        _syn.disableError = 1;
        _drawGamesContent();
        _syn.disableError = 0;
    }
    this.onProdDisableError = function () {
        _syn.selectedGameId = 0;
        _syn.disableError = 999;
        _drawGamesContent();
        _syn.disableError = 0;
    }
    this.openIframe = function (url, gid) {
        _syn.isGameRunning = 1;
        _syn.selectedGameId = gid;
        var width = 249;
        var height = 249;
        _drawGamesContent('play');
        var minigameDiv = _getElement('mini-play-frame');
        if (!minigameDiv) {
            return;
        }
        _hideMiniGameList();
        var d = {};
        d['url'] = url;
        d['width'] = width;
        d['height'] = height;
        minigameDiv.innerHTML = _template['mini-game-iframe'].getText(d);
    }
    this.isGameRunningNow = function () {
        return _syn.isGameRunning == 1;
    }
    this.onClick = function (event) {
        if (!event) event = window.event;
        if (!_onClick(event)) {
            event.returnValue = false;
            return false;
        }
        return true;
    };

    function _onClick(event) {
        var e = event.srcElement ? event.srcElement : event.target;
        while (e) {
            var id = e.id;
            e = e.parentNode;
            if (!id) continue;
            if (id == 'bu:void') return false;
            var atom = id.split(':');
            var count = atom.length;
            if (count >= 3 && atom[0] == 'bu' && atom[1] == 'mg') {
                switch (atom[2]) {
                case 'list':
                    if (count >= 4) {
                        _openGame(parseInt(atom[3], 10), atom[4]);
                    }
                    return false;
                case 'frame':
                    if (count >= 4) {
                        _closeGame(atom[3]);
                    }
                    return false;
                case 'error':
                    _removeError();
                    return false;
                }
            }
        }
        return true;
    }

    function _openGame(pff, gid) {
        var parm = 'id=' + gid + '&pff=' + pff;
        var url = _gamesSSOURL + parm;
        _submit(url);
    }

    function _closeGame(gid) {
        _syn.isGameRunning = 0;
        _drawGamesContent();
    }

    function _getGameName(gid) {
        return _template['mini-' + gid + '-word'].getText();
    }

    function _hideMiniGameList() {
        var gList = _getElement('mini-game-list');
        var gFrame = _getElement('mini-game-frame');
        if (gList && gFrame) {
            gList.className = TiLib.Text.addClassItem(gList.className, 'hide');
            gFrame.className = TiLib.Text.removeClassItem(gFrame.className, 'hide');
        }
    }

    function _showMiniGameList() {
        var gList = _getElement('mini-game-list');
        var gFrame = _getElement('mini-game-frame');
        if (gList && gFrame) {
            gList.className = TiLib.Text.removeClassItem(gList.className, 'hide');
            gFrame.className = TiLib.Text.addClassItem(gFrame.className, 'hide');
        }
    }

    function _drawGamesContent(mode) {
        var gamesBody = _getElement('right-games-body');
        if (gamesBody) {
            gamesBody.innerHTML = _draw(mode);
        }
    }

    function _removeError() {
        _syn.serverError = 0;
        _drawGamesContent();
    }

    function _submit(url) {
        return TiLib.Ajax.sendRequest('minigame', url);
    }

    function _getElement(id) {
        return document.getElementById(id);
    }

    function _draw(mode) {
        if (!_template) {
            _syn.waitingTemplate = true;
            return;
        }
        if (!_isTabEnabled) {
            return;
        }
        var d = {};
        d['available-games'] = '';
        if ((mode && mode == _syn.listModeDisp) || !mode) {
            for (var i = 0; i < _gameList.length; i++) {
                var gid = _gameList[i][0];
                d['gameid'] = gid;
                d['errorMsg'] = _syn.serverError == 1 && _syn.selectedGameId == gid ? _template['mini-game-error-msg-blk'].getText() : ((_syn.disableError == 999) || (_syn.disableError == 1 && _syn.selectedGameId == gid) ? _template['mini-game-notavl-msg-blk'].getText() : '');
                d['available-games'] += _template['mini-' + gid + '-body'].getText(d);
            }
            d['selected-games-frame'] = '';
        } else {
            d['available-games'] = '';
            d['gameid'] = _syn.selectedGameId;
            d['game-name'] = _getGameName(_syn.selectedGameId);
            d['selected-games-frame'] = _template['mini-game-play-body'].getText(d);
        }
        var res = _template['games-content'].getText(d);
        _syn.serverError = 0;
        _syn.disableError = 0;
        return res;
    }
}

function __Module_Global_Page(page) {
    var _elementDic = {};
    var _self = this;
    var _page = page;
    var _viewPortSize = {
        'width': 0,
        'height': 0
    };
    var _offsetDic = {};
    this.initiate = function () {
        TiLib.Event.addListener('viewportsize', _onWindowResize);
        TiLib.Event.addListener('scroll', _onWindowScroll);
    };
    this.disablePageScroll = function () {
        _disableScroll();
    };
    this.enablePageScroll = function () {
        _enableScroll();
    };
    this.redrawLeftColumn = function (isFromTicket, reset) {
        _redrawLeftColumn(isFromTicket, reset);
    }
    this.isSmallScreen = function () {
        return _isSmallScreen();
    }
    this.scrollDivMyBet = function () {
        _scrollDivMyBet()
    }
    this.isQuirkMode = function () {
        return _isQuirkMode();
    }
    this.hasVerticalScroll = function () {
        return TiLib.Document.getInnerHeight() != TiLib.Document.getDocumentHeight();
    }
    this.getViewPortSize = function () {
        return _viewPortSize;
    };
    this.getViewPortWidth = function () {
        return _viewPortSize.width;
    };
    this.getViewPortHeight = function () {
        return _viewPortSize.height;
    };
    this.getElementOffset = function (elementId, clearAll) {
        if (!clearAll && _offsetDic[elementId]) {
            return _offsetDic[elementId];
        }
        var element = _getElement(elementId, clearAll);
        if (element) {
            _offsetDic[elementId] = _getElementOffset(element);
            return _offsetDic[elementId];
        } else {
            return {
                'x': 0,
                'y': 0
            };
        }
    };
    this.getElementX = function (elementId, clearAll) {
        if (!clearAll && _offsetDic[elementId] && _offsetDic[elementId].x) {
            return _offsetDic[elementId].x;
        }
        var element = _getElement(elementId, clearAll);
        if (element) {
            _offsetDic[elementId] = _getElementOffset(element);
            return _offsetDic[elementId].x;
        } else {
            return 0;
        }
    };
    this.getElementY = function (elementId, clearAll) {
        if (!clearAll && _offsetDic[elementId] && _offsetDic[elementId].y) {
            return _offsetDic[elementId].y;
        }
        var element = _getElement(elementId, clearAll);
        if (element) {
            _offsetDic[elementId] = _getElementOffset(element);
            return _offsetDic[elementId].y;
        } else {
            return 0;
        }
    };
    this.incGA = function (category, position) {
        _incGA(category, position);
    }
    var _marketName = ['unknown', 'today', 'em', 'live', 'oetg', 'cs', 'htft', '1x2', 'fglg', 'mp', 'outright', 'ls', 'lsEvent', 'favourite'];

    function _incGA(category, position) {
        var marketId = _getDisplaySetting('market-page');
        if (!marketId) {
            marketId = 0;
        }
        var marketName = _marketName[parseInt(marketId)];
        try {
            if (ga) {
                ga('send', 'event', category, position, marketName);
            }
        } catch (e) {}
    }

    function _getDisplaySetting(key) {
        if ($M('odds-display')) {
            return $M('odds-display').getDisplaySetting(key);
        }
        if ($M('live-sport-display')) {
            return $M('live-sport-display').getDisplaySetting(key);
        }
        return null;
    };
    var keys = [37, 38, 39, 40];

    function _preventDefault(e) {
        e = e || window.event;
        if (e.preventDefault)
            e.preventDefault();
        e.returnValue = false;
    }

    function _keydown(e) {
        e = e || window.event;
        for (var i = keys.length; i--;) {
            if (e.keyCode === keys[i]) {
                _preventDefault(e);
                return;
            }
        }
    }

    function _wheel(e) {
        _preventDefault(e);
    }

    function _disableScroll() {
        if (window.addEventListener) {
            window.addEventListener('DOMMouseScroll', _wheel, false);
        }
        window.onmousewheel = document.onmousewheel = _wheel;
    }

    function _enableScroll() {
        if (window.removeEventListener) {
            window.removeEventListener('DOMMouseScroll', _wheel, false);
        }
        window.onmousewheel = document.onmousewheel = document.onkeydown = null;
    }

    function _onWindowResize(event) {
        if (event && event.width) {
            _viewPortSize.width = event.width;
            if (event.width >= 1252) {
                _showRightColumn();
            } else {
                _hideRightColumn();
            }
        }
        if (event && event.height) {
            _viewPortSize.height = event.height;
        }
        _onResize(event);
    }

    function _redrawLeftColumn(isFromTicket, reset) {
        var y = _getWindowScrollTop();
        var params = {
            'y': y
        };
        if (y > 0) {
            var force = isFromTicket;
            _onScroll(params, force);
        }
    };

    function _getWindowScrollTop() {
        var scrollTop = 0;
        if (_isQuirkMode()) {
            scrollTop = window.document.body.scrollTop;
        } else {
            scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
        }
        return scrollTop;
    }
    var _browserScrollbarWidth = null;

    function _getBrowserScrollbarWidth() {
        if (_browserScrollbarWidth) return _browserScrollbarWidth;
        var outer, outerStyle, scrollbarWidth;
        outer = document.createElement('div');
        outerStyle = outer.style;
        outerStyle.position = 'absolute';
        outerStyle.width = '100px';
        outerStyle.height = '100px';
        outerStyle.overflow = 'scroll';
        outerStyle.top = '-9999px';
        document.body.appendChild(outer);
        scrollbarWidth = outer.offsetWidth - outer.clientWidth;
        document.body.removeChild(outer);
        _browserScrollbarWidth = scrollbarWidth
        return _browserScrollbarWidth;
    };

    function _onWindowScroll(params) {
        var force = false;
        _onScroll(params, force);
    }

    function _showRightColumn() {
        var rightColumn = _getElement('right-column');
        if (rightColumn && rightColumn.style) {
            rightColumn.className = TiLib.Text.removeClassItem(rightColumn.className, "hide");
            _adjustMainDisplayPosition();
        }
    };

    function _hideRightColumn() {
        var rightColumn = _getElement('right-column');
        if (rightColumn && rightColumn.style) {
            rightColumn.className = TiLib.Text.addClassItem(rightColumn.className, "hide");
            _adjustMainDisplayPosition();
        }
    };

    function _adjustMainDisplayPosition() {
        var width = 0;
        if (self.innerHeight) {
            width = self.innerWidth;
        } else if (document.documentElement && document.documentElement.clientHeight) {
            width = document.documentElement.clientWidth;
        } else if (document.body) {
            width = document.body.clientWidth;
        }
        var fdiv = document.getElementById('body-inner');
        var tdiv = document.getElementById('blue-bar-inner');
        if (width < 1252) {
            if (fdiv && tdiv) {
                fdiv.className = 'normal-width body-inner';
                tdiv.className = 'normal-width blue-bar-inner';
            }
        } else {
            if (fdiv && tdiv) {
                fdiv.className = 'wide-width body-inner';
                tdiv.className = 'wide-width blue-bar-inner';
            }
        }
    };

    function _getElement(elementName, clearCache) {
        if (!_elementDic[elementName] || clearCache) {
            _elementDic[elementName] = document.getElementById(elementName);
        }
        return _elementDic[elementName];
    }

    function _getElementOffset(element) {
        var p = {
            'x': 0,
            'y': 0
        };
        if (element.offsetLeft) {
            p.x = element.offsetLeft;
            p.y = element.offsetTop;
            while (element = element.offsetParent) {
                p.x += element.offsetLeft;
                p.y += element.offsetTop;
            }
        }
        return p;
    }
    var _syn = {
        isDocking: false
    };

    function _onResize(event) {
        if (_syn.isDocking && event && event.oldWidth != event.width) {
            var elem = document.getElementById('slider-bar');
            var left = document.getElementById('left-panel');
            if (left && elem && _syn.isDocking && !_isQuirkMode()) {
                left.style.left = elem.offsetLeft + 'px';
            }
        }
        _scrollDivMyBet();
    }

    function _onScroll(params, force) {
        var sportMarket = document.getElementById('module-sport-market');
        var ticket = document.getElementById('module-ticket');
        var odds = document.getElementById('module-odds-display');
        var mybets = document.getElementById('module-mybets');
        if (odds && sportMarket && ticket && mybets && !_isQuirkMode()) {
            if (odds.scrollHeight < (mybets.scrollHeight + sportMarket.scrollHeight + ticket.scrollHeight)) {
                _scrollDivMyBet();
            }
        }
        if (params && params.y != undefined) {
            if (TiLib.Document.getScrollHeight() > TiLib.Document.getDocumentHeight() - TiLib.Document.getInnerHeight() - 300) {
                if ($M('odds-display') && $M('odds-display').extend) {
                    setTimeout(function () {
                        $M('odds-display').extend();
                    }, 500);
                }
            }
            if (_isTicketTooBig()) {
                _undock();
                return;
            }
            var limited = _getLimitedOffset();
            if (params.y >= limited && (!_syn.isDocking || force)) {
                _dock();
                _scrollDivMyBet();
            }
            if (params.y < limited && (_syn.isDocking || force)) {
                _undock();
                _scrollDivMyBet();
            }
        }
    }

    function _dock() {
        var left = document.getElementById('left-panel');
        var elem = document.getElementById('slider-bar');
        if (left && elem) {
            _syn.isDocking = true;
            if (_isQuirkMode()) {
                left.style.position = 'absolute';
                left.className = TiLib.Text.addClassItem(left.className, 'fixed-left');
            } else {
                left.style.position = 'fixed';
                left.style.top = _getLeftPosition() + 'px';
                left.style.left = elem.offsetLeft + 'px';
            }
        }
    }

    function _undock() {
        var left = document.getElementById('left-panel');
        if (left) {
            _syn.isDocking = false;
            if (_isQuirkMode()) {
                left.className = TiLib.Text.removeClassItem(left.className, 'fixed-left');
                left.style.position = 'relative';
                left.style.top = '';
            } else {
                left.style.position = 'absolute';
                left.style.top = '';
                left.style.left = '0px';
            }
        }
    }

    function _isQuirkMode() {
        var version = TiLib.Browser.getVersion();
        var hasDoctype = document.compatMode != 'BackCompat';
        return !hasDoctype && TiLib.Browser.isInternetExplorer() && (version == 8 || version == 9 || version == 7);
    }

    function _getLeftPosition() {
        var leftTopPosition = 0;
        var isOddsDisplay = $M('odds-display');
        var isMobile = TiLib.Browser.isMobileDevice();
        if (isOddsDisplay) {
            if (isMobile) {
                leftTopPosition = 35;
            } else {
                leftTopPosition = 78;
            }
        } else {
            if (isMobile) {
                leftTopPosition = 41;
            } else {
                leftTopPosition = 86;
            }
        }
        return leftTopPosition;
    }

    function _getLimitedOffset() {
        var limitedOffset = 109;
        var isOddsDisplay = $M('odds-display');
        if (isOddsDisplay) {
            var sm = document.getElementById('module-sport-market');
            if (sm) {
                limitedOffset += sm.offsetHeight;
            }
            var fav = document.getElementById('module-favourite');
            if (fav) {
                limitedOffset += fav.offsetHeight;
            }
        }
        return limitedOffset;
    }

    function _scrollDivMyBet() {
        var refreshTicket = document.getElementById('l-refresh-button-container');
        var refreshHeight = refreshTicket ? refreshTicket.scrollHeight : 0;
        var offsetTop = 4 + (_isQuirkMode() ? 102 : 140) + refreshHeight;
        if ($M('live-sport-display')) {
            if (_syn.isDocking) {
                offsetTop = 2 + (_isQuirkMode() ? 110 : 140) + refreshHeight;
            } else {
                offsetTop = 54 + (_isQuirkMode() ? 110 : 140) + refreshHeight;
            }
        }
        var ticket = document.getElementById('module-ticket');
        var ticketHeight = ticket ? ticket.scrollHeight : 0;
        var windowHeight = window.innerHeight || document.body.clientHeight;
        var newHeight = windowHeight - offsetTop - ticketHeight;
        var hasHorizontalBar = document.body.scrollWidth > document.body.clientWidth;
        var horizontalBarHeight = 0;
        if (hasHorizontalBar && !TiLib.Browser.isInternetExplorer()) {
            horizontalBarHeight = _getBrowserScrollbarWidth();
        }
        if (ticketHeight + 250 > windowHeight || !ticket.disabledScrollDiv) {
            ScrollDiv.draw('mb:pb', newHeight);
            var jumpDown = true;
            ScrollDiv.draw('tk:mp:data', windowHeight - 250 - horizontalBarHeight, jumpDown);
            return;
        }
        newHeight -= horizontalBarHeight;
        var mybet = document.getElementById('mb:pb');
        var myBetHeight = mybet ? mybet.scrollHeight : Math.max();
        newHeight = Math.min(newHeight, myBetHeight);
        if (!isNaN(newHeight) && newHeight > 0) {
            ScrollDiv.draw('mb:pb', newHeight);
        }
    }

    function _isSmallScreen() {
        var windowHeight = window.innerHeight || document.body.clientHeight;
        var smallScreen = false;
        if (windowHeight < 700 || TiLib.Browser.isMobileDevice()) {
            smallScreen = true;
        }
        return smallScreen;
    }

    function _isTicketTooBig() {
        var windowHeight = window.innerHeight || document.body.clientHeight;
        var ticket = document.getElementById('module-ticket');
        var ret = false;
        if (windowHeight < 700 && ticket) {
            ret = ticket.scrollHeight > windowHeight - 120;
        }
        return ret;
    }
}

function _ScrollDiv() {
    var _self = this;
    this.unscroll = function (id) {
        var div = document.getElementById(id);
        if (div) {
            var contentHeight = div.scrollHeight;
            div.disabledScrollDiv = true;
            div.style.height = contentHeight + 'px';
            div.style.overflow = 'hidden';
            var bar = document.getElementById(id + '-bar');
            if (bar) {
                bar.style.height = '0px';
            }
        }
    }
    this.hideRail = function (id) {
        var rail = document.getElementById(id + '-rail');
        if (rail) {
            rail.style.display = 'none';
            return;
        }
    }
    this.showRail = function (id) {
        var rail = document.getElementById(id + '-rail');
        if (rail) {
            rail.style.display = '';
            return;
        }
    }
    this.draw = function (id, defaultHeight, jumpDown, lastPosition) {
        var content = document.getElementById(id);
        if (!content) {
            return;
        }
        var windowHeight = window.innerHeight || document.documentElement.clientHeight;
        var contentHeight = content.scrollHeight;
        var offsetHeight = content.offsetTop;
        var height = defaultHeight || (windowHeight - offsetHeight);
        if (isNaN(height) || height <= 0) return;
        if (contentHeight <= height) {
            _self.unscroll(id);
            return;
        }
        content.totalScrollHeight = contentHeight - height;
        content.style.height = height + 'px';
        content.style.overflow = 'hidden';
        var rail = document.getElementById(id + '-rail');
        if (!rail) {
            var railDiv = document.createElement('div');
            railDiv.id = id + '-rail';
            var barDiv = document.createElement('div');
            barDiv.id = id + '-bar';
            railDiv.appendChild(barDiv);
            content.parentNode.appendChild(railDiv);
            rail = railDiv;
        }
        var bar = _getFirstChildNode(rail);
        if (!bar) {
            return;
        }
        content.disabledScrollDiv = false;
        var barHeight = (height / contentHeight) * height;
        content.maxScrollHeight = height - barHeight + 1;
        bar.maxScrollHeight = height - barHeight + 1;
        bar.style.height = barHeight + 'px';
        bar.style.position = 'absolute';
        rail.style.top = offsetHeight + 'px';
        rail.style.height = height + 'px';
        rail.style.position = 'absolute';
        if (jumpDown) {
            content.currentPos = content.totalScrollHeight;
            content.scrollTop = content.totalScrollHeight;
            bar.style.top = content.maxScrollHeight + 'px';
        }
        if (lastPosition && !isNaN(lastPosition)) {
            content.currentPos = lastPosition;
            content.scrollTop = lastPosition;
            bar.style.top = (lastPosition * content.maxScrollHeight / content.totalScrollHeight) + 'px';
        }
        if (!content.hasBinding) {
            if (content.addEventListener) {
                content.addEventListener('mousewheel', scroll, false);
                content.addEventListener('DOMMouseScroll', scroll, false);
                content.addEventListener('touchstart', touchStart, false);
                content.addEventListener('touchmove', touchMove, false);
                content.addEventListener('touchend', touchEnd, false);
            } else {
                if (content.attachEvent) {
                    content.attachEvent('onmousewheel', scroll);
                }
            }
            content.onmouseover = contentMouseOver;
            content.onmouseout = contentMouseOut;
            bar.onmousedown = barMouseDown;
            bar.onmouseup = barMouseUp;
            rail.onmouseover = railMouseOver;
            rail.onmouseout = railMouseOut;
            content.rail = rail;
            content.hasBinding = true;
        }
    }
    var _initYTouch = 0;

    function touchStart(e) {
        var touch = e.touches[0];
        var element = this;
        _initYTouch = touch.pageY;
        if (!element.disabledScrollDiv) {
            if (e.preventDefault) {
                e.preventDefault();
            }
            e.returnValue = false;
        }
    }

    function touchMove(e) {
        var touch = e.touches[0];
        var delta = _initYTouch - touch.pageY;
        _initYTouch = touch.pageY;
        var element = this;
        var rail = element.rail;
        if (!rail) return;
        if (element.rail && element.rail.firstChild) {
            element.rail.className = 'slimScrollRail';
            element.rail.firstChild.className = 'slimScrollBar';
        }
        if (isNaN(element.currentPos)) element.currentPos = 0;
        if (delta) {
            element.currentPos += delta;
        }
        if (element.currentPos < 0) element.currentPos = 0;
        if (element.currentPos > element.totalScrollHeight) element.currentPos = element.totalScrollHeight;
        var bar = _getFirstChildNode(rail);
        if (bar) {
            bar.style.top = (element.currentPos * element.maxScrollHeight / element.totalScrollHeight) + 'px';
        }
        element.scrollTop = (element.currentPos);
        if (!element.disabledScrollDiv) {
            if (e.preventDefault) {
                e.preventDefault();
            }
            e.returnValue = false;
        }
    }

    function touchEnd(e) {
        var element = this;
        var rail = element.rail;
        if (!rail) return;
        if (element.rail && element.rail.firstChild) {
            element.rail.className = '';
            element.rail.firstChild.className = '';
        }
        if (!element.disabledScrollDiv) {
            if (e.preventDefault) {
                e.preventDefault();
            }
            e.returnValue = false;
        }
    }

    function _getFirstChildNode(element) {
        var elements = element.childNodes;
        for (var i = 0; i < elements.length; i++) {
            if (elements[i] && elements[i].nodeType === 1) {
                return elements[i];
            }
        }
        return null;
    }

    function scroll(event) {
        var evt = event || window.event;
        var element = event.srcElement ? event.srcElement : event.target;
        if (!this.rail) {
            while (element) {
                if (element.rail) break;
                element = element.parentNode;
            }
        } else {
            element = this;
        }
        var rail = element.rail;
        if (!rail) return;
        if (isNaN(element.currentPos)) element.currentPos = 0;
        var delta = evt.delta || evt.wheelDelta || (evt.originalEvent && evt.originalEvent.wheelDelta) || -evt.detail || (evt.originalEvent && -evt.originalEvent.detail);
        if (delta > 0) delta = 20;
        else delta = -20
        if (delta) {
            element.currentPos += -delta;
        }
        if (element.currentPos < 0) element.currentPos = 0;
        if (element.currentPos > element.totalScrollHeight) element.currentPos = element.totalScrollHeight;
        var bar = _getFirstChildNode(rail);
        if (bar) {
            bar.style.top = (element.currentPos * element.maxScrollHeight / element.totalScrollHeight) + 'px';
        }
        element.scrollTop = (element.currentPos++);
        if (!element.disabledScrollDiv) {
            if (evt.preventDefault) {
                evt.preventDefault();
            }
            evt.returnValue = false;
        }
    }
    var _currentElement;
    var _currentBar;
    var _currentPos;

    function barMouseDown(event) {
        var evt = event || window.event;
        this.isActive = true;
        this.currentY = _getMouseY(evt);
        _currentBar = this;
        _currentPos = parseInt(this.style.top.replace('px', '')) || 0;
        if (!_currentElement) {
            _currentElement = document.getElementById(_currentBar.id.replace('-bar', ''));
        }
        document.onmousemove = barMouseMove;
        document.onmouseup = barMouseUp;
        if (evt && evt.preventDefault) {
            evt.preventDefault();
        } else {
            evt = false;
        }
        return false;
    }

    function barMouseUp(e) {
        if (_currentBar) {
            _currentBar.className = '';
            _currentBar.parentNode.className = '';
            _currentBar.isActive = false;
        }
        _currentBar = null;
        _currentElement = null;
        document.onmousemove = '';
        document.onmouseup = '';
    }

    function barMouseMove(e) {
        if (_currentBar && _currentBar.isActive) {
            var delta = _getMouseY(e) - _currentBar.currentY;
            var newPos = _currentPos + delta;
            if (newPos < 0) {
                newPos = 0;
            } else if (newPos > _currentBar.maxScrollHeight) {
                newPos = _currentBar.maxScrollHeight;
            }
            _currentBar.style.top = newPos + 'px';
            _currentElement.currentPos = (newPos / _currentElement.maxScrollHeight) * _currentElement.totalScrollHeight;
            _currentElement.scrollTop = _currentElement.currentPos;
        } else {
            document.onmousemove = '';
            document.onmouseup = '';
        }
        if (e && e.preventDefault) {
            e.preventDefault();
        } else {
            window.event.returnValue = false;
        }
        return false;
    }

    function railMouseOver(e) {
        this.className = 'slimScrollRail';
        this.firstChild.className = 'slimScrollBar';
    }

    function railMouseOut(e) {
        if (_currentBar && _currentBar.isActive) return;
        this.className = '';
        this.firstChild.className = '';
    }

    function contentMouseOver(e) {
        if (this.rail && this.rail.firstChild) {
            this.rail.className = 'slimScrollRail';
            this.rail.firstChild.className = 'slimScrollBar';
        }
    }

    function contentMouseOut(e) {
        if (this.rail && this.rail.firstChild) {
            if (_currentBar && _currentBar.isActive) return;
            this.rail.className = '';
            this.rail.firstChild.className = '';
        }
    }

    function _getMouseY(e) {
        var posy = 0;
        if (!e) var e = window.event;
        if (e.pageY) {
            posy = e.pageY;
        } else if (e.clientY) {
            posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
        }
        return posy;
    }
}
var ScrollDiv = new _ScrollDiv();

function __namespaceCookieHelper() {
    var _self = this;
    var _name = ['ph-param-loginname', 'ph-credit-display', 'ph-credit-display', 'mini-bl-rj-ids', 'showing-sports', 'od-param-odds-mode', 'od-param-price-style', 'od-param-live-sport-mode', 'od-param-sorting', 'od-param-market-showing', 'od-param-display-in-local-time', 'od-param-market-page', 'opened-sport-id', 'opened-market-id', 'opened-event-id', 'module-setting-odds-display', 'module-setting-live-sport-display', 'module-setting-odds-display-setting', 'module-setting-page-head', 'module-setting-sport-market', 'interested-event-body-expanded', 'interested-event-market-expanded'];
    this.getValue = function (name) {
        var value = TiLib.Cookie.getValue('states');
        var ret = null;
        if (value) {
            var values = value.split(':');
            for (var i = 0; i < _name.length; i++) {
                if (_name[i] == name) {
                    ret = values[i];
                }
            }
        }
        return ret;
    };
    this.setValue = function (name, value, seconds) {
        var expires = '';
        if (seconds) {
            var date = new Date();
            date.setTime(date.getTime() + (seconds * 1000));
            expires = '; expires=' + date.toGMTString();
        }
        var cookieValue = TiLib.Cookie.getValue('states');
        var values = [];
        if (cookieValue) {
            values = cookieValue.split(':');
        }
        for (var i = 0; i < _name.length; i++) {
            if (_name[i] == name) {
                values[i] = value;
            }
        }
        document.cookie = 'states=' + values.join(':') + expires + '; path=/';
    };
    this.getNames = function (prefix) {
        var names = [];
        var ca = _name;
        for (var i = 0; i < ca.length; i++) {
            var name = ca[i];
            if (name.length > 0) {
                if (!prefix || name.indexOf(prefix) == 0) {
                    names.push(name);
                }
            }
        }
        return names;
    };
};
var CookieHelper = new __namespaceCookieHelper();